views:

130

answers:

3

What does this from General Recommandation #3 mean?

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.

Can someone explain by examples please?

-- Source: MSDN - Managed Threading Best Practices

+1  A: 

I take this to mean that you shouldn't manually create worker threads to handle tasks (e.g. save a file), but rather have a system in place (or use ThreadPool.QueueUserWorkItem) where you can enqueue a task/job and an existing worker is waiting for a task to arrive (perhaps using a monitor Wait or an AutoResetEvent). Doing it this way means you can re-use threads rather than having to constantly create and destroy them.

.NET 4.0 has a new built-in Task class with a bunch of supporting classes to make this style of programming easier so that you don't have to re-invent this in each project.

Jeff Moser
A: 

I think this recommendation may also be referring to creating a thread, and then repeatedly calling methods like Suspend and Resume on it to control when it runs.

It is generally considered better form to have the thread execute a while loop that contains some kind of locking primitive (like a ManualResetEvent or some similar primitive) to signal the thread when there is more work to be done.

jerryjvl
+1  A: 

Well, there are basically two ways you can dole out work to your worker threads. The first is to store work items in a queue. When you have work to do, you push it onto the queue and signal the workers. Your worker threads would look something like this:

while( !quit ) {
    WaitForWork();
    GetWorkItem();
    ExecuteWorkItem();
}

This is the approach you're supposed to take, according to the recommendation.

The other approach is to maintain a queue of workers. When you have work that you need to do, you grab a worker from the queue (or create one if its empty) and tell it to run the item. This second approach is more difficult to code and is generally less efficient.

Peter Ruderman
Thanks alot, but what is Monitor.PulseAll() used for in this blocking thread scenario? I'm referring to the last sentence in MS recommendation.
aschoenebeck
It's actually a pretty strange sentence. Monitor.PulseAll is a way to wake threads that have blocked with a call to Monitor.Wait. I'm honestly not sure what they're driving at. Maybe they're just encouraging you to use the monitor wait/pulse semantics.
Peter Ruderman