2008-11-27 76 views
5

对于我来说,这是一个相对常见的任务,我认为,对于很多.NET程序员来说:我想使用.NET ThreadPool来调度需要处理给定类型的工作线程的ThreadPool任务。.NET中的通用线程池

先来回顾一下,对于线程池及其相关委托的排队方法的签名是:

public static bool QueueUserWorkItem (
    WaitCallback callBack, 
    Object state 
) 
public delegate void WaitCallback (Object state) 

因此,一个典型的通用工作线程类看起来是这样的:

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 
    } 
} 

注意state参数的类型?这是Object

.NET团队选择不使QueueUserWorkItem方法(或整个ThreadPool类)具有通用性的原因是什么?我不敢相信他们只是忽略了它。

这是我想怎么看呢:

//in the ThreadPool class: 
public static bool QueueUserWorkItem<T> (
    WaitCallback<T> callBack, 
    T state 
) 
public delegate void WaitCallback<T> (T state) 

这将使工人阶级类型安全(和很多更清晰,恕我直言):

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 
    } 
} 

我必须失去了一些东西。

回答

5

这听起来像你在谈论一个工作队列? (我听起来像clippy ...)

为了记录,线程池线程应该通常用于短小的工作。理想情况下,您应该为长寿命队列创建自己的线程。请注意,.NET 4.0可能会采用CCR/TPL库,因此我们将免费获得一些内置工作队列 - 但编写线程化工作队列并不困难。你可以使它通用,太;-p

重的问题 - 我更喜欢捕捉变量的方法来穿过状态成线(无论是ThreadThreadPool,或Control.Invoke):

Thread t = new Thread(() => SomeMethod(arg)); 
    t.IsBackground = true; 
    t.Name = "Worker n"; 
    t.Start(); 

这使您可以更细致地控制线程,而不会使ThreadPool饱和。

+2

我不明白你不使用线程池的工作队列的基本“执行”层的说法。使用*时,这是一个问题。NET ThreadPool类由于线程数量有限吗?海事组织很自然地假设工作队列中的任务很短。你能否详细说明一下? – 2008-11-27 15:52:30

7

由于通过将匿名委托或lambda传递给线程池(通过变量捕获)来封装任何你喜欢的状态是微不足道的,因此不需要通用版本。

例如,你可以写一个效用函数:

static void QueueItem<T>(Action<T> action, T state) 
{ 
    ThreadPool.QueueUserWorkItem(delegate { action(state); }); 
} 

但它不会是非常有用的,因为你可以简单地使用委托自己,你需要在合并的任务状态的任何时间。

1

从.NET 1.1开始,ThreadPool不存在泛型。

我喜欢他们如何选择不打破向后兼容性:-)

+5

我不认为这是一个有效的论据。只要看看1.1中的所有容器类,它们在2.0中被“升级”为使用泛型。另外,我并不是建议用它的通用副本替换Queue ...方法,而是在它旁边添加通用版本。 – 2008-11-27 15:54:48