C# TPL数据流,块故障处理程序中的异常不会传播

C# TPL数据流,块故障处理程序中的异常不会传播,c#,task-parallel-library,tpl-dataflow,C#,Task Parallel Library,Tpl Dataflow,我正在使用TPL数据流块来处理消息流。我的数据流网络由两个块组成,一个缓冲块和一个动作块,动作块定义为: _actionBlock = new ActionBlock<Func<Task>>((Action<Func<Task>>) ProcessRequest, new ExecutionDataflowBlockOptions() { MaxDegr

我正在使用TPL数据流块来处理消息流。我的数据流网络由两个块组成,一个缓冲块和一个动作块,动作块定义为:

        _actionBlock = new ActionBlock<Func<Task>>((Action<Func<Task>>) ProcessRequest,
            new ExecutionDataflowBlockOptions()
            {
                MaxDegreeOfParallelism = 4,
            });
问题是抛出内部不会传播到任何地方,应用程序只是像吞没异常一样继续运行。我的代码中没有任何其他异常处理程序。作为一个实验,我已经试过了

使用重新引发异常

   Dispatcher.CurrentDispatcher.Invoke(() => throw ...)
检查ContinueWith内容是否在UI线程上运行

使用以下方法处理任何顶级异常:

currentDomain.UnhandledException += new UnhandledExceptionEventHandler(ToplevelHandler);
抛出的异常从未到达TopLevelHandler

这些都没有帮助


如何使我在ContinueWith函数中抛出的异常传播到应用程序顶部,并使应用程序退出并显示错误消息?

引自C Cookbook中的Concurrency Stephen Cleary:

要捕获数据流块中的异常,请等待其完成 所有物Completion属性返回将要完成的任务 当区块完成时,如果区块出现故障,则完成任务也会出现故障


引用C烹饪书Stephen Cleary中的Concurrency:

要捕获数据流块中的异常,请等待其完成 所有物Completion属性返回将要完成的任务 当区块完成时,如果区块出现故障,则完成任务也会出现故障


当您抛出inner时,您需要在某个时间点等待该任务来传播异常。_actionBlock运行时间很长。我在应用程序启动时创建它,在正常情况下,它会在应用程序的整个过程中持续运行。代码中没有一个自然点可以让我等待它完成任务而不阻塞所有内容。不幸的是,这就是异常结束的地方。但在这种情况下,ActionBlock出现故障,无论如何都不会继续处理。您可以在流内处理异常,也可以将异常附加到流的结果,以便在流外处理。@James actionblock总是长时间运行的。如果您想在块完成后处理异常,尽管是故障或正常完成,您需要等待它。ContinueWith将仅在ActionBlock完成时运行。@至于未传播的异常,您编写了TaskFactory.StartNew=>throw new exception;的等效程序;。如果您不等待该任务,异常将消失。您希望该错误显示在何处?当您抛出inner时,您需要在某个时间点等待该任务以传播异常。\u actionBlock正在长时间运行。我在应用程序启动时创建它,在正常情况下,它会在应用程序的整个过程中持续运行。代码中没有一个自然点可以让我等待它完成任务而不阻塞所有内容。不幸的是,这就是异常结束的地方。但在这种情况下,ActionBlock出现故障,无论如何都不会继续处理。您可以在流内处理异常,也可以将异常附加到流的结果,以便在流外处理。@James actionblock总是长时间运行的。如果您想在块完成后处理异常,尽管是故障或正常完成,您需要等待它。ContinueWith将仅在ActionBlock完成时运行。@至于未传播的异常,您编写了TaskFactory.StartNew=>throw new exception;的等效程序;。如果您不等待该任务,异常将消失。您希望该错误显示在何处?
currentDomain.UnhandledException += new UnhandledExceptionEventHandler(ToplevelHandler);
actionBlock = new ActionBlock<Func<Task>>((Action<Func<Task>>) ProcessRequest,
    new ExecutionDataflowBlockOptions()
    {
        MaxDegreeOfParallelism = 4,
    });
await actionBlock.Completion;