C# - ThreadPool.QueueUserWorkItem()要求

时间:2010-04-22 21:05:56

标签: c# multithreading .net-3.5 threadpool

我有一个Windows服务,有很多工作要做。我查看了线程并找到了ThreadPool类。我现在卡住了,它似乎没有任何影响,就像我排队的任何东西都没有运行或调用。在服务的OnStart()事件中,我创建了一个这样的线程:

Thread mainThread = new Thread(ReceiveMessages);
mainThread.Start();

在方法ReceiveMessages()中,我有一个例程,它检查消息队列,然后遍历消息。对于每次迭代,我调用以下代码来处理每条消息:

ThreadPool.QueueUserWorkItem(new WaitCallback(delegate(object state)
{
    Interpreter.InsertMessage(encoding.GetBytes(MessageBody));
}), null);

我认为语法是对的,它编译没有问题,但我不禁觉得我错过了什么。当我运行该服务时,没有任何反应。但是,如果我用以下代码替换上面的代码片段:

insertThread = new Thread(delegate() { Interpreter.InsertMessage(encoding.GetBytes(MessageBody)); });
insertThread .Start();

100%工作。它虽然效率不高并且可能导致服务崩溃(偶尔也会这样,我之所以尝试使用TheadPool)。任何人都可以对这个问题有所了解吗?

2 个答案:

答案 0 :(得分:2)

您似乎在等待回调中在MessageBody上创建了a closure。如果在线程池执行工作项时调用者的 MessageBody属性为null,则InsertMessage将运行该属性。

您需要定义一个Interpreter.InsertMessage的重载,它接受一个对象并使用 作为您的WaitCallback

public void InsertMessage(object messageBody) {
    this.InsertMessage((byte[])messageBody);
}

然后将消息体字节作为第二个参数传递:

ThreadPool.QueueUserWorkItem(new WaitCallback(Interpreter.InsertMessage), 
                             encoding.GetBytes(MessageBody));

答案 1 :(得分:1)

默认情况下,当您创建新线程时,该线程为Foreground thread。但是,ThreadPool线程将IsBackground设置为true。

这意味着线程池线程不会使您的应用程序保持活动状态。这可能就是为什么它永远不会“运行” - 它只是立即关闭。

  

虽然效率不高并且可能导致服务崩溃(偶尔也会这样,我之所以尝试使用TheadPool)。任何人都可以对这个问题有所了解吗?

自构造的线程应该同样有效(一旦线程启动并运行)。 ThreadPool线程不会以任何方式帮助“崩溃” - 你仍然需要适当地调试你的服务。