简体   繁体   English

C#-ThreadPool.QueueUserWorkItem()要求

[英]C# - ThreadPool.QueueUserWorkItem() Requirements

I have a windows service that has a lot of work to do simultaneously. 我有一个Windows服务,需要同时执行很多工作。 I've looked into threading and found the ThreadPool class. 我研究了线程并找到ThreadPool类。 I'm currently stuck, it doesn't seem to have any effect, it's like whatever I'm queuing is never run or called. 我目前陷入困境,似乎没有任何效果,就像我排队的东西永远不会运行或调用。 In the service's OnStart() event I create a thread like this: 在服务的OnStart()事件中,我创建一个如下线程:

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

Inside the method ReceiveMessages() I have a routine that checks a message queue and then iterates through the messages. 在方法ReceiveMessages()中,我有一个例程,该例程检查消息队列,然后遍历消息。 For each iteration I call the following code to do some work with each message: 对于每次迭代,我调用以下代码对每个消息进行一些处理:

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

I think the syntax is right, it compiles with no issues, but I can't help but feel that I am missing something. 我认为语法是正确的,可以毫无问题地进行编译,但是我不禁感到自己缺少一些东西。 When I run the service, nothing happens. 当我运行该服务时,什么都没有发生。 However, if I replace the above code snippet with this: 但是,如果我将上面的代码片段替换为:

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

It works 100%. 它可以100%工作。 It's not very efficient though and can cause the service to crash (which is does occasionally, the reason why I'm trying to use TheadPool instead). 它不是很有效,但是会导致服务崩溃(偶尔会这样做,这就是我尝试使用TheadPool的原因)。 Can anyone shed some light on the subject? 谁能阐明这个问题?

It looks like you're creating a closure over MessageBody in your wait callback. 似乎您正在等待回调中通过MessageBody创建一个闭包 If the caller's MessageBody property is null by the time the thread pool executes the work item, then that's what InsertMessage will operate on. 如果在线程池执行工作项时调用方的 MessageBody属性为null,则InsertMessage将对其进行操作。

You need to define an overload of Interpreter.InsertMessage that accepts an object and use that as your WaitCallback : 您需要定义一个Interpreter.InsertMessage的重载,该重载接受一个对象并将用作WaitCallback

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

Then pass the message body bytes as the second parameter: 然后将消息正文字节作为第二个参数传递:

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

By default, when you create a new Thread, the thread is a Foreground thread . 默认情况下,创建新线程时,该线程是“ 前台线程” ThreadPool threads, however, have IsBackground set to true. 但是,ThreadPool线程的IsBackground设置为true。

This means that a threadpool thread will not keep your application alive. 这意味着线程池线程将无法使您的应用程序保持活动状态。 This is probably why it's never "running" - it's just shutting down right away. 这可能就是为什么它永远不会“运行”的原因-它只是立即关闭。

It's not very efficient though and can cause the service to crash (which is does occasionally, the reason why I'm trying to use TheadPool instead). 它不是很有效,但是会导致服务崩溃(偶尔会这样做,这就是我尝试使用TheadPool的原因)。 Can anyone shed some light on the subject? 谁能阐明这个问题?

The self-constructed thread should be just as efficient (once the thread is up and running). 自构造线程应同样高效(一旦线程启动并运行)。 The "crashing" will not be helped in any way by the ThreadPool thread - you'll still need to debug your service appropriately. ThreadPool线程不会以任何方式帮助“崩溃”-您仍然需要适当地调试服务。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM