我想知道是否有一个简洁的方式来替代IDataflowBlock.Completion
来取代ReceiveAsync
或类似的方法使用取消令牌从BufferBlock
或其他IDataflowBlock
消耗。C#使用DataflowBlock.Completion取消消费者任务而不是CancellationToken
IDataflowBlock.ReceiveAsync<T>(TimeSpan, CancellationToken)
如果InputQueue
是BufferBlock
:
BufferBlock<String> InputQueue
for (int i = 0; i < 26; i++)
{
await InputQueue.SendAsync(((char)(97 + i)).ToString());
}
如果InputQueue.Complete();
被调用,那么当队列被清空,IDataflowBlock.Completion
将变为状态RanToCompletion, 可与IDataflowBlock.Completion.IsCompleted
进行检查。
如果将多个线程从队列中,这可能发生在InputQueue.ReceiveAsync
服用,有一个整洁的替代处理InputQueue
不是完成:
try
{
String parcel = await InputQueue.ReceiveAsync(timeSpan);
}
catch(InvalidOperationException x)
{
}
你的样品try-catch不是你处理完成的方式。你应该在调用'.Complete()'后等待block.Completion'。实际上正在做什么?此外,除非您有特殊的理由需要使用'RecieveAsync',否则您应该更喜欢使用'LinkTo'方法创建的块之间的链接。 [Stephen Cleary - 数据流介绍](https://blog.stephencleary.com/2012/09/introduction-to-dataflow-part-1.html) – JSteward
我有许多生产者任务将数据包放在其中的代码一个缓冲区块和许多其他任务正在从缓冲区块读取,读者任务有一个令牌,通知他们何时没有更多的生产者加载队列。鉴于该逻辑类似于isCompleted逻辑,我正在寻求消除对令牌的需求。我会考虑链接到 –
当然,在'TPL-Dataflow'中肯定会看到'LinkTo',你的消费任务将根据你的需要变成'ActionBlock'或'TransformBlock'。一旦他们被链接,你只需传播完成来关闭你的管道。 – JSteward