C# NET中的生产者/消费者模式,能够等待提交的任务/作业完成

C# NET中的生产者/消费者模式,能够等待提交的任务/作业完成,c#,.net,multithreading,asynchronous,C#,.net,Multithreading,Asynchronous,我正试图了解下面的设计,但没有弄清楚 我有许多生产者向队列提交任务/作业。然后,消费者/工人会拿起这些文件并完成这些文件。目前,只有一个消费者/工人 到目前为止,这听起来像是标准的生产者/消费者模式,可以通过BlockingCollection实现 然而,一些制作人可能希望提交一个任务/作业并能够等待其完成(或提交多个任务/作业并等待部分或全部任务/作业,等等),而其他制作人可能只是“解雇并忘记”他们的任务/作业。 (请注意,这不是等待队列为空,而是等待特定的任务/作业) 如何做到这一点?在我看

我正试图了解下面的设计,但没有弄清楚

我有许多生产者向队列提交任务/作业。然后,消费者/工人会拿起这些文件并完成这些文件。目前,只有一个消费者/工人

到目前为止,这听起来像是标准的生产者/消费者模式,可以通过BlockingCollection实现

然而,一些制作人可能希望提交一个任务/作业并能够等待其完成(或提交多个任务/作业并等待部分或全部任务/作业,等等),而其他制作人可能只是“解雇并忘记”他们的任务/作业。 (请注意,这不是等待队列为空,而是等待特定的任务/作业)

如何做到这一点?在我看到的所有示例中,生产者都只是使用BlockingQueue.Add()将数据发布到队列中


非常感谢您的帮助。

一种常见的方法是使用
TaskCompletionSource
包装您的工作操作,其
任务可以返回给调用方并等待完成

public class ProducerConsumerQueue
{
    private readonly BlockingCollection<Action> queue = new BlockingCollection<Action>();

    public Task Produce(Action work)
    {
        var tcs = new TaskCompletionSource<bool>();
        Action action = () =>
        {
            try
            {
                work();
                tcs.SetResult(true);
            }
            catch (Exception ex)
            {
                tcs.SetException(ex);
            }
        };
        queue.Add(action);
        return tcs.Task;
    }

    public void RunConsumer(CancellationToken token)
    {
        while (true)
        {
            token.ThrowIfCancellationRequested();
            var action = queue.Take(token);
            action();
        }
    }
}
公共类ProducerConsumerQueue
{

private readonly BlockingCollection。

为您放入队列的对象的类声明添加一个AutoResetEvent。与其创建一堆线程,不如直接使用它们,让它们在没有实际工作要做的时候无所事事。我很抱歉,但仍然没有得到它。不要过多地使用它etail,这是关于与另一个系统的(基于套接字的)通信。线程仍在运行以维护套接字(如果关闭,请重新连接),执行一些低级通信等。生产者希望将消息排队等待发送,有些则希望等待消息实际送达。这有意义吗?不需要使用TCS。只需使方法
异步
。这实际上总是比尽可能使用显式TCS更可取,而且几乎是alw可能。@Servy:我不明白。如果我使用async,
product
方法会将
Func
排入队列,但它会返回什么?我已经进一步阅读了你的其他评论;我明白你的意思。我同意。也许我错了,但我坚持生产者希望将工作放入队列,消费者会处理这些。我同意我不知道“使方法异步”(哪一个?)如何解决这个问题。