【问题标题】:TPL.Dataflow message processing timeout?TPL.Dataflow 消息处理超时?
【发布时间】:2014-01-08 11:24:37
【问题描述】:

使用 .NET TPL DataFlow 块。 有没有办法让消息处理超时?

例如

假设我有一个BufferBlock<T>,是否可以将其链接到一次处理一条消息的另一个块 (MaxDegreeOfParallellism1) 并在处理运行时间过长时强制超时? 或者甚至可以只使用 BufferBlock 吗?

我怀疑我可以以某种方式使用取消令牌和延迟,但不确定如何做到这一点。 另外,这样的超时会有多贵?是否会增加消息处理时间的开销?

【问题讨论】:

  • 我认为没有内置超时。如果您只想过滤这些项目,而不仅仅是删除为其他项目腾出空间,则可以创建一个块。
  • “强制超时”到底是什么意思?你想cancel a non-cancelable operation吗? (我说的是您的处理代码,而不是数据流中的任何内容。)

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


【解决方案1】:

BufferBlock<T> 的许多方法都接受CancellationToken,我相信这将是使操作超时的正确方法。例如:

var cts = new CancellationTokenSource(5000); // cancel in 5s 
// Alternatively: cts.CancelAfter(5000);

try 
{
    var output = await bufferBlock.ReceiveAsync(cts.Token);
}
catch (Exception ex)
{
    // check if ex is OperationCanceledException,
    // which could be wrapped with AggregateException 
}

IMO,评估其效率的唯一方法是运行一些分析测试。

[UPDATE] 基于 cmets,如果您希望使管道处理超时,您可以在构造 ActionBlock 对象并为其提供实例时执行此操作的ExecutionDataflowBlockOptions。此时,您可以提供DataflowBlockOptions.CancellationToken 并以与上述相同的方式使用它。此外,您可以将CancellationToken 作为DataflowLinkOptions 的一部分传递给LinkTo

为管道提供CancellationToken 后,您可以跟踪ActionBlock.Completion/TransformBlock.Completion 的状态,即Task,因此您可以await 它并捕获取消异常,或使用ContinueWith(如果这是您在某种方式来判断消息的“处理”是否超时下的意思)。

免责声明:我自己没有尝试过,有兴趣知道它是否按预期工作。

【讨论】:

  • 谢谢,如果接收超时,上面的代码将取消,我需要一些方法来判断消息的“处理”是否超时。但是,如果我通过处理器将消息通过管道传输并将其转发到另一个块,那么可能是某种类似的方式
  • @RogerAlsing,我想是的。您可能会为此使用token.Register 和/或CreateLinkedTokenSource。也许你可以展示你的处理代码的草图。
  • 应该超时的代码位于此处突出显示的行:github.com/rogeralsing/Pigeon/blob/master/Pigeon/Actor/… 我在那里使用缓冲块作为可观察对象,但这绝不是要求,我只是想调用“ onNext" 一旦我收到来自缓冲区块的消息,如果它执行超过 x 次,则抛出
猜你喜欢
  • 2020-02-15
  • 2019-10-03
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-06-09
相关资源
最近更新 更多