2010-04-22 27 views
0

我有一个Windows服务,有很多工作要同时完成。我研究了线程并找到了ThreadPool类。我目前卡住了,似乎没有任何效果,就像我排队的任何东西都不会运行或调用。在服务的的OnStart()事件中,我创建这样一个主题:C# - ThreadPool.QueueUserWorkItem()要求

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

它看起来像你在等待回调中创建a closure而不是MessageBody。如果调用者的MessageBody属性在线程池执行工作项时为空,那么这就是InsertMessage将操作的内容。

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

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

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

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

这是完美的!奇迹般有效! – 2010-04-22 21:32:34

1

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

这意味着线程池线程不会让您的应用程序保持活动状态。这可能是它永远不会“运行”的原因 - 它只是马上关闭。

虽然它不是非常有效,但可能导致服务崩溃(偶尔会出现这种情况,因为我试图使用TheadPool)。任何人都可以谈谈这个问题吗?

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

+0

我明白你在说什么。 ReceiveMessages()有一个while(true)循环,它不断检查消息队列,所以每次有消息时,每条消息都会得到它自己的线程来完成一些工作。也许这有某种影响? – 2010-04-22 21:25:40

+0

@Mr。 Smith:如果主线程终止,你将关闭应用程序(如果你使用的是ThreadPool线程),因为你需要至少有一个非后台线程来保持它活着...... – 2010-04-22 21:31:07

+0

是的,但不是' t我在OnStart()事件中做什么?你说创建一个新的Thread默认是一个Foreground线程,是不是会让我的第一个代码片段中的mainThread超出一个会保持活动状态的线程?我只使用该线程内的ThreadPool。你怎么看? – 2010-04-22 21:54:12