我很擅长使用Blocking Collection和线程,并希望确保我遵循最佳做法。我使用的是非线程安全的第三方API。我将同时向API发出多个请求,因此我需要将这些请求添加到队列中并一个接一个地处理它们。要做到这一点,我有一个阻止集合:
BlockingCollection<myEventArgs> myTasks = new BlockingCollection<myEventArgs>();
private void myEventHandler(object sender, myEventArgs e)
{
myTasks.Add(e);
}
private void doWork()
{
while (myTasks.IsCompleted == false)
{
//Do some work here with the third party API.
var eArgs = myTasks.Take();
//Sometimes I have a background (thread safe) task to perform.
//This is submitted to the thread pool.
Task.Run(() => doSomeBackgroundWork());
}
}
有时我会有一个我想要执行的线程安全后台任务。例如,API调用是异步的,我需要轮询第三方系统以检查任务是否完成。我不希望这会阻止BlockingCollection处理下一个任务,所以我将其提交给线程池。一旦线程池任务完成,它将触发一个事件,该事件向BlockingCollection添加一个新任务。
此解决方案是否合适?这有什么可能出错吗?我是否正确假设处理来自BlockingCollection的项的doWork方法将始终在同一个线程中运行?当我从线程池中触发事件时,只有事件将在线程池上运行,而不是后续的doWork方法?
答案 0 :(得分:2)
此解决方案是否合适
基本上,是的。这是生产者/消费者的情况,这正是BlockingCollection的用途。
有什么可能出错吗?
您必须非常确定doSomeBackgroundWork()
对于您的doWork()代码是线程安全的。
最好在您的blockingcollection上设置一个上限,这取决于可以推送多少个myEventArgs。
答案 1 :(得分:0)
我知道这是一个旧线程,但是为了读者,我想指出的是,以这种方式进行操作与仅生成没有阻塞集合的线程相同,因此消除了BlockingCollection的全部内容
在这种情况下,更合适的方法是管理线程数,并且仅在使用BlockingCollection时才产生特定数量的线程,这将确保不会同时产生太多线程< / p>