如何制作转发任务完成信息的透明 ContinueWith 回调?
How to make a transparent ContinueWith callback which forwards the task completion information?
我有一个 Task
和 ContinueWith
回调。然而,这是在 returns Task
的单独函数中,因此调用者可以选择添加更多 ContinueWith
回调或做任何他想做的事情。我需要一种方法使第一个 ContinueWith
回调透明,以便它传递结果(不难)以及 Exception
属性(这似乎更难)。
如果我重新抛出异常,如果调用者没有添加另一个可以处理它的 ContinueWith
回调,我会遇到一个问题,它会未经处理地掉到我想要的外部 space避免。
另一方面,我不知道如何将现有的 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
。
您描述的情况无法完成。要让异常流过您的延续,您需要抛出它。
您可以做的不过是在同一个任务上添加多个延续,而不是将它们链接起来。第一个确保异常得到处理,其他人可以使用结果(或异常):
Task task = ...
task.ContinueWith(
_ => MyExceptionHandler.Handle(_.Exception),
TaskContinuationOptions.OnlyOnFaulted);
task.ContinueWith(_ =>
{
if (_.Exception)
{
// ...
}
});
我有一个 Task
和 ContinueWith
回调。然而,这是在 returns Task
的单独函数中,因此调用者可以选择添加更多 ContinueWith
回调或做任何他想做的事情。我需要一种方法使第一个 ContinueWith
回调透明,以便它传递结果(不难)以及 Exception
属性(这似乎更难)。
如果我重新抛出异常,如果调用者没有添加另一个可以处理它的 ContinueWith
回调,我会遇到一个问题,它会未经处理地掉到我想要的外部 space避免。
另一方面,我不知道如何将现有的 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
。
您描述的情况无法完成。要让异常流过您的延续,您需要抛出它。
您可以做的不过是在同一个任务上添加多个延续,而不是将它们链接起来。第一个确保异常得到处理,其他人可以使用结果(或异常):
Task task = ...
task.ContinueWith(
_ => MyExceptionHandler.Handle(_.Exception),
TaskContinuationOptions.OnlyOnFaulted);
task.ContinueWith(_ =>
{
if (_.Exception)
{
// ...
}
});