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)
    {
        // ...
    }
});