This is not a question or issue, I just simply realized that this could appear in anyone’s code where content loading is done on a different thread.
So, the basic scenario:
- You have a lot of contents that you want to load before the game starts.
- You do not want to block the main thread, so obviously you will create a different thread for this loading logic.
- In the main thread you show a loading screen to the user, show some progress and basically you keep the user informed that everything is under control and he needs to wait some seconds.
Sounds quite simple, right? Well, it is simple, but there is a big danger! Why? Well, first of all you have created the new thread on the main thread. Possibly, you have a loading method that is called from your main Update method if you need to load your contents. Usualy you create a variable for storing the loading state, so you can make sure everything is called when it needs to be called. This variable has values, like “loading_required”, “loading_started”, “loading_textures”, etc… Obviously, the loading thread creation must only be called exactly once, when the variable has the “loading_required” value. When it has any different value, you simply update a message on the screen or animate a loading icon, or something, meanwhile the background thread starts and loads all of your contents.
In an ideal world, the very first command in your thread creation is to set the loading variable to “loading_started”. YOU_MUST_NOT_FORGET_THIS! At the moment when you start running your background thread, the game loop also starts to continue its job, so at that time you will have two separate threads. The latter you set the loading variable to something different than “loading_required”, the bigger the chance that the game reaches the next Update call, and this will call your loading logic again and because there is no guarantee that your background thread updated the loading variable, it can still be “loading_required”. What does it mean? Well, because it is nearly impossible to debug a multithreaded code, you will end up tearing your hair as you may have two or even more background thread, though you expected only one and this will result in absurd situations!
So, in a nutshell: always keep an eye of your multithreaded logic and update the thread controlling variables state as soon as possible! In an event-based application you have more straightforward control of your logic, but in an XNA-style app you cannot really control when and how the Update and Draw methods are called, therefore sometimes you need additional state checking and need to be more cautios.
I hope this small “article” was not too long and will save you a lot of time handling your background threads!