问题描述
我不熟悉使用阻塞收集和线程,并希望确保我遵循最佳实践.我正在使用不是线程安全的第三方 API.我将同时向 API 发出多个请求,因此我需要将这些请求添加到队列中并一个接一个地处理它们.为此,我有一个阻塞集合:
I'm new to using Blocking Collection and threading and want to make sure I'm following best practice. I'm using a third party API that is not thread safe. I will be making multiple simultaneous requests to the API, so I need to add these requests to a queue and process them one after another. To do this I have a blocking collection:
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.
Sometimes I will have a thread safe background task I want to perform. For example, the API calls are asynchronous and I need to poll the third party system to check if a task is complete. I don't want this to prevent the BlockingCollection from processing the next task, so I submit this to the thread pool. Once the thread pool task is complete it will fire an event, which adds a new task to the BlockingCollection.
这个解决方案是否合适&这有什么问题吗?我是否正确假设处理来自 BlockingCollection 的项目的 doWork 方法将始终在同一线程中运行?当我从线程池中触发事件时,只有事件会在线程池上运行,而不是后续的 doWork 方法?
Is this solution appropriate & is there anything that could go wrong with this? Am I correct to assume that the doWork method that processes items from the BlockingCollection will always run in the same thread? And when I fire events from the threadpool, only the event will run on the thread pool, and not the subsequent doWork method?
推荐答案
基本上,是的.这是生产者/消费者的情况,而这正是 BlockingCollection 的用途.
Basically, yes. It is a Producer/Consumer situation and that's precisely what the BlockingCollection is for.
这有什么问题吗?
您必须非常确定 doSomeBackgroundWork()
就您的 doWork() 代码而言是线程安全的.
You have to be very sure that the doSomeBackgroundWork()
is thread-safe with respect to your doWork() code.
根据可以推送多少 myEventArgs,为您的阻塞集合设置上限可能是个好主意.
It might be a good idea to put a ceiling on Your blockingcollection, dependng on how many myEventArgs can be pushed.
这篇关于c#阻塞收集和线程的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!