简体   繁体   English

C#等待收藏

[英]C# awaitable collection

Is there a standard way to await for a collection to be marked as complete by another task (thread?) I am looking for something like await collection.Completion.Task 有没有一种标准的方法来等待一个集合被另一个任务标记为完成(线程?)我正在寻找像await collection.Completion.Task这样的东西。

So far I found the following approaches: 到目前为止,我发现了以下方法:

  • Use a TaskCompletionSource variable (needs to be shared with the other task/thread) 使用TaskCompletionSource变量(需要与其他任务/线程共享)
  • Use a BlockingCollection and do a while(!collection.IsAddingCompleted) {} (not async) 使用BlockingCollection并执行一段while(!collection.IsAddingCompleted) {} (不是异步)
  • Use a BufferBlock<T> from TPL Dataflow and do an await bufferBlock.Completion.Task (probably lots of overhead?) 使用来自TPL Dataflow的BufferBlock<T>并执行await bufferBlock.Completion.Task (可能有很多开销?)
  • Use an ObservableCollection (not async) 使用ObservableCollection (不是异步)
  • Any other? 任何其他?

All thoughts appreciated 所有的想法都赞赏

EDIT: Adding scenario to give more context 编辑:添加方案以提供更多上下文

class Program
{
    static void Main(string[] args)
    {
        var list = new List<int>();
        var tcs = new TaskCompletionSource<bool>();

        //This thread represents an independent process which will populate the list
        new Thread(() =>
            {
                for (int i = 0; i < 5; i++)
                {
                    Thread.Sleep(200); // do work
                    list.Add(i);
                }
                tcs.SetResult(true);
                Thread.Sleep(2000); //do more work
                Console.WriteLine("The End -- Press Enter");
                Console.ReadLine();
            }
        ).Start();

        //This task awaits for the list to be populated
        new Task(async () =>
        {
            await Task.Delay(300); //do work
            await tcs.Task;
            Console.WriteLine("List count = " + list.Count);
        }).Start();
    }
}

Is there a standard way to await for a collection to be marked as complete by another task? 有没有一种标准的方法来等待一个集合被另一个任务标记为完成?

You can use any kind of "signal" for this. 您可以使用任何类型的“信号”。 Since this is just a one-time signal, TaskCompletionSource<T> would be fine. 由于这只是一次性信号,因此TaskCompletionSource<T>会没问题。 The fact that it's a collection-completed signal is immaterial. 事实上,它是一个收集完成的信号是无关紧要的。 Though, as you found, some collections do have this built-in. 但是,正如您所发现的,某些集合确实具有此内置功能。

To address each of your questions: 要解决您的每个问题:

  • TaskCompletionSource<T> - the most straightforward, IMO, since it can be used with any kind of collection. TaskCompletionSource<T> - 最简单的IMO,因为它可以与任何类型的集合一起使用。
  • BlockingCollection<T> - You wouldn't want to use BlockingCollection , but you can use an AsyncProducerConsumerQueue or AsyncCollection , which are the same abstraction but allowing asynchronous waits. BlockingCollection<T> - 您不希望使用BlockingCollection ,但您可以使用AsyncProducerConsumerQueueAsyncCollection ,它们是相同的抽象但允许异步等待。
  • BufferBlock<T> - Also fine. BufferBlock<T> - 也没关系。 A lot of people use BufferBlock<T> as an async-compatible producer/consumer queue. 很多人使用BufferBlock<T>作为异步兼容的生产者/消费者队列。
  • ObservableCollection<T> - not an option since it doesn't have the notion of "completion". ObservableCollection<T> - 不是一个选项,因为它没有“完成”的概念。
  • Others - If your collection is "push-based", you can use IObservable<T> and just await it. 其他 - 如果您的集合是“基于推送”,则可以使用IObservable<T>await它。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM