感谢您的帮助。我有一个三线程进程,由并发队列链接。线程1处理信息,返回第二个线程,将第二个线程放入并发队列。第三个线程就像这样循环:
while (true) {
if(queue.TryDequeue(out info)) {
doStuff(info);
} else {
Thread.Sleep(1);
}
}
有没有更好的方法来处理它,这样我就不会在循环中迭代这么多?该应用程序对性能非常敏感,目前仅TryDequeue
占用了应用程序运行时的~8-9%。希望尽可能减少这一点,但不确定我的选择是什么。
答案 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);
}
将此放在每次修改队列时调用的方法中,这可确保它在需要时运行,但在不需要时结束。