C#使用DataflowBlock.Completion取消消费者任务而不是CancellationToken

时间:2017-06-08 11:04:11

标签: c# task-parallel-library tpl-dataflow

我想知道IDataflowBlock.Completion是否有一种巧妙的方法来替换需要使用ReceiveAsync的取消令牌或类似的方法,这种方法消耗来自BufferBlock或其他{ {1}}。

IDataflowBlock

如果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();将更改为状态 RanToCompletion 时, 可以使用IDataflowBlock.Completion进行检查。

如果多个线程从队列中取出,这可能发生在IDataflowBlock.Completion.IsCompleted期间,是否有更简洁的替代方法来处理InputQueue.ReceiveAsync完成:

InputQueue

1 个答案:

答案 0 :(得分:0)

cancel a Dataflow Block最简单的方法是将令牌提供给块的构造函数,如下所示:

CREATE OR REPLACE RULE skip_unique AS ON INSERT TO account WHERE (EXISTS (SELECT 1 FROM account WHERE NEW.value->>'opCo' = OLD.value->>'opCo' AND NEW.value->>'customerId' = OLD.value->>'customerId')) DO INSTEAD NOTHING;
CREATE OR REPLACE RULE skip_unique AS ON INSERT TO account WHERE (EXISTS (SELECT 1 FROM account AS b WHERE b.value->>'opCo' = account.value->>'opCo' AND b.value->>'customerId' = account.value->>'customerId')) DO INSTEAD NOTHING;
CREATE OR REPLACE RULE skip_unique AS ON INSERT TO account old WHERE (NEW.value->>'opCo' = old.value->>'opCo' AND NEW.value->>'customerId' = old.value->>'customerId') DO INSTEAD NOTHING;

CancellationToken is defined in Dataflow​Block​Options class,即使new ExecutionDataflowBlockOptions { CancellationToken = cancellationSource.Token }); 也可以取消。

为什么要自己实施BufferBlock逻辑?将PropagateCompletionlinking your blocks一起使用是否有一些限制?例如,如果您的代码如下所示:

Receive

然后你可以像这样使用internal void HandleMessage() { try { var parcel = await InputQueue.ReceiveAsync(timeSpan); // handle parsel } catch(InvalidOperationException x) { } }

ActionBlock

另请注意,如果您需要与UI进行某些互动,则可以将最后一个块用作IObservable Rx.Net库。