我正在使用 TPL 数据流 block 来处理消息流。我的数据流网络由两个 block 组成,一个BufferBlock和一个ActionBlock,其中action block 定义为:
_actionBlock = new ActionBlock<Func<Task>>((Action<Func<Task>>) ProcessRequest,
new ExecutionDataflowBlockOptions()
{
MaxDegreeOfParallelism = 4,
});
如果操作 block 内发生错误,我想让错误向上传播并退出应用程序。稍后,我计划在此处添加逻辑来处理 transient 错误,但目前,任何错误都应导致应用程序退出并显示故障详细信息。为此,我添加了一个如下的ContinueWith部分:
_actionBlock
.Completion
.ContinueWith(dbt =>
{
var inner = dbt.Exception.InnerExceptions.First();
throw inner;
},
TaskContinuationOptions.OnlyOnFaulted
);
问题是“内部抛出”不会传播到任何地方,应用程序只是继续执行,就像异常被吞掉一样。我的代码中没有任何其他异常处理程序。作为一个实验,我尝试过
使用
重新抛出异常Dispatcher.CurrentDispatcher.Invoke(() => throw ...)
检查ContinueWith 内容是否正在UI 线程上运行。
使用以下方法处理任何顶级异常:
currentDomain.UnhandledException += new UnhandledExceptionEventHandler(ToplevelHandler);
(抛出的异常永远不会到达TopLevelHandler)
这些都没有帮助。
如何使在ContinueWith函数内抛出的异常传播到应用程序顶部并使应用程序退出并显示错误消息?
最佳答案
引用 C# Cookbook 中的并发(Stephen Cleary):
To catch exceptions from a Dataflow block, await its Completion property. The Completion property returns a Task that will complete when the block is completed, and if the block faults, the Completion task is also faulted.
actionBlock = new ActionBlock<Func<Task>>((Action<Func<Task>>) ProcessRequest,
new ExecutionDataflowBlockOptions()
{
MaxDegreeOfParallelism = 4,
});
await actionBlock.Completion;
关于c# - TPL 数据流, block 故障处理程序中的异常不会传播,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53394806/