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.
What the snippet means is that:
Suppose you have a producer-consumer problem for which you have a consumer thread. If you have a dedicated thread(non ThreadPool) then you should use the WaitHandle::WaitOne call to make that thread wait until you have something to process (maybe in a process queue). When the producer is done filling up the queue, it can call WaitHandle::Set() to notify you thread to start processing the queue. WaitOne() is for dedicated threads because it will be expensive to create a new dedicated thread every time you want to process the queue.
ThreadPool threads are recommended for small tasks so if you plan to use WaitOne() then you should not use ThreadPool threads because ThreadPool is a global resource available to every application and blocking the pool threads is not a good option.