c#阻塞收集和线程
本文关键字:线程 | 更新日期: 2023-09-27 18:15:34
我是使用阻塞集合和线程的新手,并希望确保我遵循最佳实践。我使用的是不线程安全的第三方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方法?
这个方案合适吗
基本上,是的。这是一个生产者/消费者的情况,这正是BlockingCollection的作用。
这个有什么问题吗?
您必须非常确定doSomeBackgroundWork()
相对于您的doWork()代码是线程安全的。
我知道这是一个老线程,但为了读者的缘故,我想指出,这样做,是一样的,只是产卵线程没有阻塞集合,从而消除了BlockingCollection的整个点。
在这种情况下,更合适的方法是管理线程的数量,并且在使用BlockingCollection时只产生特定数量的线程,这样可以确保同时不会产生太多的线程