如何制作一个透明的ContinueWith回调来转发任务完成信息?

时间:2016-02-12 16:21:03

标签: c# task-parallel-library task

我正在Task进行ContinueWith回调。但是,这是一个单独的函数,它返回Task,因此调用者可以选择添加更多ContinueWith回调或做他想做的任何事情。我需要一种方法来使第一个ContinueWith回调透明,以便它传递结果(不是很难)以及Exception属性(这似乎更难)。

如果我重新抛出异常,如果调用者没有添加另一个将处理它的ContinueWith回调,那么我就会遇到问题,并且它将无法处理到我想要避免的外部空间。

另一方面,我不知道如何在不抛出现有任务的情况下将现有Exception添加到当前任务中。

以下是一些示例代码。

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

更新

我确实注意到Exception确实传播了,但它被重新包装成新的AggregateException

1 个答案:

答案 0 :(得分:1)

您所描述的内容无法完成。为了让异常流过你的延续,你需要抛出它。

可以做什么但是在同一个任务上添加多个延续而不是链接它们。第一个确保处理异常,其他人可以使用结果(或异常):

Task task = ...
task.ContinueWith(
    _ => MyExceptionHandler.Handle(_.Exception),
    TaskContinuationOptions.OnlyOnFaulted);
task.ContinueWith(_ =>
{
    if (_.Exception)
    {
        // ...
    }
});