Useful hint: Beware of using multithreading in XNA-style framework

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! :slightly_smiling:

Cheers!

3 Likes

That’s sounds like a common threading issue: synchronisation.

You didn’t mention lock, if the update status variable isn’t locked, people would face weird/un-understandable issue (assuming they are new to threading). Also notice threaded code cannot be really debugged like single process program (because thread live all together doing their work in a unpredictable way.)

Also one important thing to remember (MS devs seems to ignore it): sharing the same limited resource multiple time (typically the disk) WILL NOT improve performance overall ! You’ll get the opposite actually.

Not exactly as it happens before the new thread(s) are even started. Because XNA calls Update in a regular basis, it is very likely that if you do something wrong or “too late”, your logic will be called multiple times even though you expected it to be called only once. This is the reason why I wrote the above, to give a hint about the cause of this problem.
For a long time I simply thought that the problem lies in the calling of FileStream operation inside a background thread rather than on a UI thread and yesterday I just accidentally realized that multiple threads are launched instead of one and not having any locking they tried to access the same file at the same time. :slightly_smiling:

Very informative and inspired me to look into creating multi threaded content loading! Thank you :slightly_smiling:

I thank you! :slightly_smiling: Feel free to ask for help, if you need any!

Thanks a lot for this, Kuz, I was looking for exactly this. Given that I am starting to really take start-up time with loading and generating things, I too decided to move this to a new thread, so I searched for an article like this.
One note, why explicitly set the “loading_started” at the beginning? If we start on the assumption that the first thing the application does is to start loading/preparing things, I believe we are safe to start with that variable set to true directly, instead of us setting it so. Then, we can turn it off when we’re done.