c# 阻塞收集和线程

c# Blocking Collection and Threading

我刚开始使用阻塞收集和线程,希望确保我遵循了最佳实践。我正在使用非线程安全的第三方 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 方法?

Is this solution appropriate

基本上是的。这是一种 Producer/Consumer 情况,而这正是 BlockingCollection 的用途。

is there anything that could go wrong with this?

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

根据可以推送的 myEventArgs 的数量,为您的 blockingcollection 设置上限可能是个好主意。

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

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