gpt4 book ai didi

c# - 下游 block 中的 TPL 数据流和异常处理

转载 作者:行者123 更新时间:2023-11-30 14:23:14 30 4
gpt4 key购买 nike

我有以下伪代码:

var queue = new BufferBlock<int>(new DataflowBlockOptions { BoundedCapacity = 5 });
var a = new ActionBlock<int>(async item =>
{
await Task.Delay(500);
Trace.TraceInformation(
$"Target 1: | Type: {typeof(int).Name} | Thread: {Thread.CurrentThread.ManagedThreadId} | Message: {item}");
// handling some logic but it throws
if (item >= 5) throw new Exception("Something bad happened");

}, new ExecutionDataflowBlockOptions { BoundedCapacity = 1, MaxDegreeOfParallelism = 1 });

queue.LinkTo(a, new DataflowLinkOptions { PropagateCompletion = true });

var targets = new List<ITargetBlock<int>> {queue};

var broadcaster = new ActionBlock<int>(
async item =>
{
var processingTasks = targets.Select(async t =>
{
try
{
// This is condition is always false
// t (bufferblock) has no exceptions. Exception is raised in downstream action block where it sends to
if (!await t.SendAsync(item))
await t.Completion;
}
catch (Exception e)
{
Trace.TraceInformation("Handled exception : " + e.Message);
}
});

try
{
// Neither here the exception is rethrowed
await Task.WhenAll(processingTasks);
}
catch (Exception e)
{
Trace.TraceInformation("Handled exception WhenAll : " + e.Message);
}
});

for (var i = 1; i <= 10; i++)
{
broadcaster.Post(i);
}

管道是这样配置的ActionBlock<int> => BufferBlock<int> => ActionBlock<int> .

最后ActionBlock<int>抛出一个异常,但它没有被重新抛出到我想处理它的源代码块。

如何重写这段代码以正确处理异常?

最佳答案

您可以找到该主题的官方指南 here .整体解决方案是订阅所有区 block Completion检查其状态的任务,并在需要时更换故障 block (也应该存储 block 的所有引用)。请参阅整篇文章以获取更多信息。

Behaviors of a network with Faulted blocks

  1. Reserved Messages
    In order to avoid message corruption, a faulted block should clear its message queues and move into a Faulted state as soon as possible. There is a single scenario that does not obey to this rule: a source block holding a message reserved by a target. If a block that encounters an internal exception has a message that was reserved by a target, the reserved message must not be dropped, and the block should not be moved into the Faulted state until the message is released or consumed.

  2. Hanging Networks
    ...

    • Keep a reference to all the blocks in the network and use Task.WaitAll or Task.WhenAll to wait for them (synchronously or asynchronously). If a block faults, its Completion task will complete in the Faulted state.
    • Use DataflowLinkOptions with PropagateCompletion == true when building a linear network. That will propagate block completion from source to target. In this case it is enough to wait on the network leaf block.

关于c# - 下游 block 中的 TPL 数据流和异常处理,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46104379/

30 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com