【问题标题】:C# - ThreadPool.QueueUserWorkItem() RequirementsC# - ThreadPool.QueueUserWorkItem() 要求
【发布时间】:2011-02-11 06:38:42
【问题描述】:

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

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

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

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

我认为语法是正确的,它编译没有问题,但我不禁觉得我错过了一些东西。当我运行该服务时,什么也没有发生。但是,如果我将上面的代码 sn-p 替换为:

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

它 100% 有效。虽然它不是很有效,并且可能导致服务崩溃(偶尔会发生,这就是我尝试使用 TheadPool 的原因)。任何人都可以对这个主题有所了解吗?

【问题讨论】:

    标签: c# multithreading .net-3.5 threadpool


    【解决方案1】:

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

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

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

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

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

    【讨论】:

    • 太完美了!像魅力一样工作!
    【解决方案2】:

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

    这意味着线程池线程不会让您的应用程序保持活动状态。这可能就是它从不“运行”的原因——它只是立即关闭。

    虽然它的效率不是很高,并且可能导致服务崩溃(这偶尔会发生,这也是我尝试改用 TheadPool 的原因)。任何人都可以对这个主题有所了解吗?

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

    【讨论】:

    • 我明白你在说什么。 ReceiveMessages() 有一个 while(true) 循环,它不断检查消息队列,所以每次有消息时,每条消息都会有自己的线程来做一些工作。也许这有某种影响?
    • @Mr. Smith:如果主线程终止,您将关闭应用程序(如果您使用的是 ThreadPool 线程),因为您需要至少有一个非后台线程才能使其保持活动状态......
    • 是的,但这不是我在 OnStart() 事件中所做的吗?您说创建一个新线程默认情况下是一个前台线程,这不会使我的第一个代码 sn-p 中的 mainThread 高于一个可以使其保持活动状态的线程吗?我只在该线程内使用 ThreadPool。你怎么看?
    猜你喜欢
    • 2022-06-10
    • 2011-02-04
    • 2023-04-06
    • 1970-01-01
    • 1970-01-01
    • 2011-09-05
    • 2011-03-04
    • 2014-07-29
    • 1970-01-01
    相关资源
    最近更新 更多