0

I've been having an issue with creating a new thread to update the audio engine while the main thread performs allocations and gc's from the process of creating a new level scene.

It works for the most part and it solved the problem of the music cutting out during level transition but occasionally or perhaps after a certain number of level loads it hangs and I have to close the game down from task manager so no error message pops up unfortunately.

Basically I have it set up like this:

audioThread = new Thread(new ThreadStart(updateAudio));
audioThread.IsBackground = true;
audioThread.Start();

// Allocate new level objects and initialise world

audioThread.Abort();

The audio thread method is just an infinite loop:

private void updateAudio() {
    while(true)
        Assets.audioEngine.Update();
}

I'm very new to multi-threading and thread safety in c# so any advice at all would be awesome.

Thanks, Marios

EDIT: I switched the threads around and used locks like this:

audioUpdateThread = new Thread(new ThreadStart(setupWorld));
audioUpdateThread.IsBackground = true;
audioUpdateThread.Start();
lockHelp.loadingLevel = true;
updateAudio();

The main thread updates the audio now:

while(true)
{
    Assets.audioEngine.Update();
    lock (lockHelp)
        if (!lockHelp.loadingLevel)
            break;
}
audioUpdateThread.Abort();

When the new thread is done loading the level it locks the helper object and sets loadingLevel to false:

lock (lockHelp)
    lockHelp.loadingLevel = false;

I've not had any problems now but a playtester did get a hang at level load.

Mazk1985
  • 43
  • 4
  • You might want to change these operations around - do the audio on the main thread / let XNA play it and offload content loading to another thread. – Vaughan Hilts Aug 04 '13 at 18:46
  • @Vaughan Hilts. Will I need to synchronise a variable for the main thread to check when the loading is done? Is that how you properly handle read/write from multiple threads to a variable? Using synchronisation? – Mazk1985 Aug 04 '13 at 20:44
  • Yes, you use locks and syncing in most cases. However, I'd like to point out that if you simply have a callback and don't modify other state on another thread, you're OK. i'd reccomend having a 'loading state' which is animated - and then another another screen in the background that is being loaded async. Since your loading screen is active and music is still playing - it'll be okay. As long as you don't touch the resources being loaded or that screen on anohter thread. Just fire a callback and pop the loading screen off. I can write a full answer if you're interested. – Vaughan Hilts Aug 04 '13 at 20:46
  • @Vaughan Hilts. Thanks man. That sounds like a good way to do it. The levels are quite small and the transition is quite quick but I'll definitely try out pre loading the next world object on another thread before the transition (I assume that's what you meant) so all I have to do is swap the worlds round and no allocating needs to be done at transition. I'll save the previous world until the player hits the exit so the new thread can sort out the previous world's gc operations before preloading the next level. With any luck that will avoid the hacky nature of the while loop audio update – Mazk1985 Aug 06 '13 at 16:34

0 Answers0