c#阻塞收集和线程

c#阻塞收集和线程,c#,multithreading,thread-safety,threadpool,blockingcollection,C#,Multithreading,Thread Safety,Threadpool,Blockingcollection,我不熟悉使用阻塞收集和线程,希望确保遵循最佳实践。我使用的第三方API不是线程安全的。我将同时向API发出多个请求,因此我需要将这些请求添加到队列中,并逐个处理它们。为此,我有一个阻塞集合: BlockingCollection<myEventArgs> myTasks = new BlockingCollection<myEventArgs>(); private void myEventHandler(object sender, myEventAr

我不熟悉使用阻塞收集和线程,希望确保遵循最佳实践。我使用的第三方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());

        }
    }
BlockingCollection myTasks=new BlockingCollection();
私有void myEventHandler(对象发送方,MyEventTargs e)
{
添加(e);
}
私房
{
while(myTasks.IsCompleted==false)
{
//在这里使用第三方API做一些工作。
var eArgs=myTasks.Take();
//有时我要执行后台(线程安全)任务。
//这将提交到线程池。
运行(()=>doSomeBackgroundWork());
}
}
有时我会有一个线程安全的后台任务,我想执行。例如,API调用是异步的,我需要轮询第三方系统以检查任务是否完成。我不希望这阻止BlockingCollection处理下一个任务,所以我将其提交到线程池。线程池任务完成后,它将触发一个事件,向BlockingCollection添加一个新任务

这个解决方案合适吗?是否有任何问题?我假设处理BlockingCollection中的项的doWork方法将始终在同一线程中运行,对吗?当我从线程池触发事件时,只有事件会在线程池上运行,而不是后续的doWork方法

这个解决方案合适吗

基本上,是的。这是生产者/消费者的情况,这正是BlockingCollection的目的

这有什么问题吗

您必须非常确定
doSomeBackgroundWork()
对于doWork()代码是线程安全的


在你的blockingcollection上设置一个上限可能是个好主意,这取决于可以推送多少myEventArgs

我知道这是一个旧线程,但为了读者起见,我想指出,这样做与在没有阻塞集合的情况下生成线程是一样的,因此删除了整个阻塞集合点


在这种情况下,更合适的做法是管理线程的数量,并且在使用BlockingCollection时只生成特定数量的线程,这样可以确保不会同时生成太多线程

我认为DoWork()需要一个循环,在它内部或周围。是的,对不起,有一个循环,我只是解释了我的代码!为了清晰起见,我现在将其添加进来。另一方面,标准的C#实践要求对方法和类型进行PASCALCING。太好了,非常感谢。doSomeBackgroundWork()方法本质上是一个SQL select语句,用于查询第三方作业管理器。它不会更新或更改任何内容,因此应该是安全的。是的,如本例所示,它使用了四个线程: