我有一个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)。任何人都可以对这个问题有所了解吗?
答案 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线程不会以任何方式帮助“崩溃” - 你仍然需要适当地调试你的服务。