C# 如何通过回调转发任务完成信息来实现透明的连续性?
我有一个C# 如何通过回调转发任务完成信息来实现透明的连续性?,c#,task-parallel-library,task,C#,Task Parallel Library,Task,我有一个任务,有一个连续的回调。但是,这是在一个单独的函数中,该函数返回任务,因此调用者可以选择添加更多ContinueWith回调或执行任何他想要的操作。我需要一种方法使第一个ContinueWith回调透明,以便它向前传递结果(不难)和异常属性(这似乎更难) 如果我重新抛出异常,我会遇到一个问题,如果调用方没有添加另一个ContinueWith回调来处理它,那么它将未经处理掉到我想要避免的外部空间 另一方面,我不知道elso I如何将现有的异常添加到当前任务而不抛出它 下面是一些示例代码 T
任务
,有一个连续的
回调。但是,这是在一个单独的函数中,该函数返回任务
,因此调用者可以选择添加更多ContinueWith
回调或执行任何他想要的操作。我需要一种方法使第一个ContinueWith
回调透明,以便它向前传递结果(不难)和异常
属性(这似乎更难)
如果我重新抛出异常,我会遇到一个问题,如果调用方没有添加另一个ContinueWith
回调来处理它,那么它将未经处理掉到我想要避免的外部空间
另一方面,我不知道elso I如何将现有的异常添加到当前任务而不抛出它
下面是一些示例代码
Task.Factory.StartNew(() => {
throw new Exception("test");
}).ContinueWith(t => {
// this is my general handler
MyExceptionHandler.Handle(t.Exception);
// etc...
// HERE set the Exception for the current task to forward it
return t.Result; // result forwarded
}).ContinueWith(t => {
// this MIGHT be appended by consumer code
if (t.Exception) // HERE I would like to see the exception which might have been thrown be the original task.
// do whatever ...
});
更新
我实际上注意到,异常
确实被传播,但它被重新包装成一个新的聚合异常
您所描述的无法完成。要让异常通过您的延续,您需要抛出它
但是,您可以在同一任务上添加多个延续,而不是将它们链接起来。第一种方法确保异常得到处理,其他方法可以使用结果(或异常):
这里的执行顺序是确定的吗?在成功和失败的情况下(实际上在任何情况下,也包括取消),我都需要公共的ContinueWith
处理程序。在这种情况下是否定义了执行顺序?我目前找不到任何关于这方面的文档。我接受了你的回答,因为我意识到执行顺序在我的情况下并不重要(我正在一般的延续中进行记录)。谢谢。你说的未处理是什么意思?它没有通过MyExceptionHandler.Handle
?或者该任务将引发未观察到的TaskException
事件?否,它将通过它。如果我在之后重新显示t.Exception
,则返回此选项。但根据我上次的测试,这并不重要,我没有意识到确切的行为。看我的更新。我看到了更新,这就是我问的原因。您想使用t.GetAwaiter().GetResult()
而不是t.Result
。它不会将异常包装在一个aggregateeexception
中。请记住,除非使用者添加了另一个延续,否则您添加的延续将创建一个包含未处理异常的任务。是的,这就是问题所在。我将使用你在回答中提供的方法,谢谢。这将是好的,即使秩序是不确定的。
Task task = ...
task.ContinueWith(
_ => MyExceptionHandler.Handle(_.Exception),
TaskContinuationOptions.OnlyOnFaulted);
task.ContinueWith(_ =>
{
if (_.Exception)
{
// ...
}
});