告诉我是否更新了并发队列而没有循环

时间:2015-08-07 19:21:04

标签: c# multithreading concurrency

感谢您的帮助。我有一个三线程进程,由并发队列链接。线程1处理信息,返回第二个线程,将第二个线程放入并发队列。第三个线程就像这样循环:

while (true) {
    if(queue.TryDequeue(out info)) {
        doStuff(info);
    } else {
        Thread.Sleep(1);
    }
}

有没有更好的方法来处理它,这样我就不会在循环中迭代这么多?该应用程序对性能非常敏感,目前仅TryDequeue占用了应用程序运行时的~8-9%。希望尽可能减少这一点,但不确定我的选择是什么。

3 个答案:

答案 0 :(得分:2)

您应该考虑使用System.Collections.Concurrent.BlockingCollection及其Add()/ Take()方法。使用Take(),您的第三个线程将在等待新项目时暂停。 Add()是线程安全的,可以被第二个线程使用。

通过这种方法,您应该能够将代码简化为:

screengod(['path/to/your.css'],function(){
    /* do your stuff */
});

答案 1 :(得分:0)

您可以增加睡眠时间。我也会用await Task.Delay而不是睡觉。这样,您可以等待更长时间,而无需Thread.Sleep使用的额外cpu周期,并且仍然可以通过使用CancellationTokenSource来取消延迟。

另一方面,有更好的排队工作方式。考虑到你似乎想要同步运行这些作业,一个例子就是有一个单例类来获取你的工作项并将它们排队。因此,如果添加一个项目时队列中没有项目,它应检测到该项目,然后开始您的作业流程。在作业结束时,检查更多工作,使用递归来完成该工作,或者如果没有更多作业,则退出作业进程,当您将项添加到空队列时,该进程将再次运行。如果我的假设是错误的并且您可以并行运行这些作业,为什么要使用队列?

您可能希望使用ObservableCollection的线程安全实现。看看这个问题ObservableCollection and threading

答案 2 :(得分:0)

我没有避免循环的建议,但我建议你离开

while (true)

并考虑一下:

MyThing thing;
while (queue.TryDequeue(out thing))
{
    doWork(thing);
}

将此放在每次修改队列时调用的方法中,这可确保它在需要时运行,但在不需要时结束。