[英]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: 到目前为止,我发现了以下方法:
TaskCompletionSource
variable (needs to be shared with the other task/thread) 使用TaskCompletionSource
变量(需要与其他任务/线程共享) BlockingCollection
and do a while(!collection.IsAddingCompleted) {}
(not async) 使用BlockingCollection
并执行一段while(!collection.IsAddingCompleted) {}
(不是异步) BufferBlock<T>
from TPL Dataflow and do an await bufferBlock.Completion.Task
(probably lots of overhead?) 使用来自TPL Dataflow的BufferBlock<T>
并执行await bufferBlock.Completion.Task
(可能有很多开销?) ObservableCollection
(not async) 使用ObservableCollection
(不是异步) 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
,但您可以使用AsyncProducerConsumerQueue
或AsyncCollection
,它们是相同的抽象但允许异步等待。 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>
- 不是一个选项,因为它没有“完成”的概念。 IObservable<T>
and just await
it. 其他 - 如果您的集合是“基于推送”,则可以使用IObservable<T>
并await
它。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.