A snippet from Managed Threading Best Practices
on MSDN:
Don't control the execution of worker threads from your main program (using events, for example). Instead, design your program so that worker threads are responsible for waiting until work is available, executing it, and notifying other parts of your program when finished. If your worker threads do not block, consider using thread pool threads. Monitor..::.PulseAll is useful in situations where worker threads block.
I want to know what this describes so I can search for basic implementations to start working with.