Here’s a relatively common task for me, and, I think, for many a .NET programmer:
I want to use the .NET ThreadPool for scheduling worker threads that need to process a given type of tasks.
As a refresher, the signatures for the queueing method of the ThreadPool and its associated delegate are:
public static bool QueueUserWorkItem ( WaitCallback callBack, Object state ) public delegate void WaitCallback (Object state)
Therefore, a typical generic worker thread class would look something like:
public class Worker<T> { public void schedule(T i_task) { ThreadPool.QueueUserWorkItem(execute, i_task) } private void execute(Object o){ T task = (T)o; //What happened to the type safety? executeTask(task); } private void executeTask(T i_task){ //process i_task } }
Notice the type of the state parameter? It’s Object !
What’s the compelling reason why the .NET team chose not to make the QueueUserWorkItem method (or the whole ThreadPool class) generic? I can’t believe they just overlooked it.
Here’s how I’d like to see it:
//in the ThreadPool class: public static bool QueueUserWorkItem<T> ( WaitCallback<T> callBack, T state ) public delegate void WaitCallback<T> (T state)
This would make the worker class type-safe (and a lot clearer, IMHO):
public class Worker<T> { public void schedule(T i_task) { ThreadPool.QueueUserWorkItem<T>(execute, i_task) } private void execute(T i_task){ //process i_task } }
I must be missing something.
It sounds like you are talking about a work queue? (and I sound like clippy…)
For the record, thread-pool threads should typically be used for short pieces of work. You should ideally create your own threads for a long-lived queue. Note that .NET 4.0 may be adopting the CCR/TPL libraries, so we’ll get some inbuilt work queues for free – but it isn’t hard to write a threaded work-queue. And you can make it generic, too ;-p
Re the question – I prefer the captured variables approach to passing state into threads (be they
Thread,ThreadPool, orControl.Invoke):This gives you much more granular control over the thread, without saturating the
ThreadPool.