Best Practice for Multithreading Procedural Terrain Generation?

I’m trying to make infinite procedurally generated chunk based terrain. Because the generation of block data and vertex/triangle arrays takes a while I’m trying to put as much as I can on a second thread.

Currently I have a background thread checking which chunks need to be loaded, generating them if they’re not already calculated and adding them to a dictionary of chunks to load which my main thread then looks at during the regular update cycle and uses to instantiate the generated chunks. This approach seems to be working in theory, the logic is sound at least and the chunks generate and are instantiated as they should be but the background thread just stops working after a little while. It seems to stop arbitrarily (sometimes 2 seconds, sometimes 20 seconds) although notably I can get it to stop by causing a spike in the rendering requirements (suddenly looking at an area of the world which has a lot stuff to render).

Checking the thread state reveals that it is alive but not running. It’s not being blocked by the main thread because if I comment out all the critical sections from the main thread, the background thread still freezes after a few seconds of running.

I’ve tried using

    lock(lockObject){}  

as well as

    AutoResetEvent.WaitOne()  

but the problem persists. I’m not sure if the structure I’ve set up isn’t really conducive to decent multithreading or if I’m misusing the thread synchronization methods/keywords.

If it is the way I’ve structured my program, how would I structure it in such a way that works? And if it isn’t that, then what is it about the way I’m using threads that’s causing things to go wrong? Thanks!

Well, it highly depends on your actual implementation and what kind of interactions happen between your threads. Keep in mind when a exception is thrown inside your thread, the thread will get terminated silently. However IsAlive will not be false in this case because it returns:

true if this thread has been started
and has not terminated normally or
aborted; otherwise, false.

You may want to check the ThreadState instead. However if an exception is thrown it would make more sense to track down the actual problem which is the cause of the exception.

Again you haven’t provided any information which could help to track down the issue.