tags:

views:

84

answers:

3

Is it possible to purge a ThreadPool?

Remove items from the ThreadPool?

Anything like that?

ThreadPool.QueueUserWorkItem(GetDataThread);
RegisteredWaitHandle Handle = ThreadPool.RegisterWaitForSingleObject(CompletedEvent, WaitProc, null, 10000, true);

Any thoughts?

+3  A: 

There's no interface for removing a queued item. However, nothing stops you from "poisoning" the delegate so that it returns immediately.

edit

Based on what Paul said, I'm thinking you might also want to consider a pipelined architecture, where you have a fixed number of threads reading from a blocking queue (like .NET 4.0's BlockingCollection on a ConcurrentQueue). This way, if you want to cancel items, you can just access the queue yourself.

Having said that, Stephen's advice about Task is likely better, in that it gives you all the control you would realistically want, without all the hard work that rolling your own pipelines involves. I mention this only for completion.

Steven Sudit
Steven: Do you mean adding something to the `GetDataThread` that causes it to return?
jp2code
Yes, exactly. Something that new jobs check at the start and immediately fail upon detecting. A `volatile bool` will do.
Steven Sudit
To reiterate what Stephen said, cancellation inherently involves a race condition, so you should expect it to only stop jobs before they start. Arguably, you can check for the cancel flag at other convenient intervals, but that's a bit iffy.
Steven Sudit
For some reason, this was just downvoted, despite being completely correct.
Steven Sudit
+1  A: 

The ThreadPool exists to help you manage your threads. You should not have to worry about purging it at all since it will make the best performance decisions on your behalf.

If you think you need tighter control over your threads then you could consider creating your own thread management class (similar to ThreadPool) but it would take a lot of work to match and exceed the functionality that ThreadPool has built in.

Take a look here at some of the ThreadPool optimizations and the ideas behind it.

For my second point, I found an article on Code Project that implements a "Cancelable Threadpool", probably for some of your own similar reasons. It would be a good place to start looking if you're going to write your own.

Paul Sasik
The Code Project article uses `Abort`, which is not a great idea. That said, you have a point about there perhaps not being any real need to purge the pool.
Steven Sudit
+4  A: 

I recommend using the Task class (added in .NET 4.0) if you need this kind of behaviour. It supports cancellation, and you can have any number of tasks listening to the same cancellation token, which enables you to cancel them all with a single method call.

Updated (non-4.0 solution):

You really only have two choices. One: implement your own event demultiplexer (this is far more complex than it appears, due to the 64-handle wait limitation); I can't recommend this - I had to do it once (in unmanaged code), and it was hideous.

That leaves the second choice: Have a signal to cancel the tasks. Naturally, RegisteredWaitHandle.Unregister can cancel the RWFSO part. The QUWI is more complex, but can be done by making the action aware of a "token" value. When the action executes, it first checks the token value against its stored token value; if they are different, then it shouldn't do anything.

One major thing to consider is race conditions. Just keep in mind that there is a race condition between cancelling an action and the ThreadPool executing it, so it is possible to see actions running after cancellation.

I have a blog post on this concept, which I call "asynchronous callback contexts". The CallbackContext type mentioned in the blog post is available in the Nito.Async library.

Stephen Cleary
Excellent advice.
Steven Sudit
+1, but Management does not want .NET 4.0 implemented in our infrastructure at this time.
jp2code
@jp2code: That is too bad; .NET 4.0 brings huge, useful changes to multithreading in .NET. See my updated answer for a pre-.NET 4.0 solution.
Stephen Cleary