如何正确地重新抛出已经处于故障状态的任务的异常?

avo*_*avo 7 .net c# task-parallel-library async-await

我有一个同步方法,除其他外,它检查挂起任务的状态并重新抛出其异常,如果有的话:

void Test(Task task)
{
    // ...
    if (task.IsFaulted)
        throw task.Exception;
    // ...
}
Run Code Online (Sandbox Code Playgroud)

这不会传播异常堆栈跟踪信息,并且对调试器不友好.

现在,如果Testasync,它将不会像这样简单和自然:

async Task Test(Task task)
{
    // ...
    if (task.IsFaulted)
        await task; // rethrow immediately and correctly
    // ...
}
Run Code Online (Sandbox Code Playgroud)

问题:如何正确执行同步方法?我想出了这个,但我不喜欢它:

void Test(Task task)
{
    // ...
    if (task.IsFaulted)
        new Action(async () => await task)();
    // ...
}
Run Code Online (Sandbox Code Playgroud)

Ste*_*ary 16

要正确地重新抛出异常,您应该使用ExceptionDispatchInfo:

ExceptionDispatchInfo.Capture(task.Exception.InnerException).Throw();
Run Code Online (Sandbox Code Playgroud)

可以这样做:

task.GetAwaiter().GetResult();
Run Code Online (Sandbox Code Playgroud)

PS您的Action方法将无法正常工作,因为您正在创建一个async void方法,并且您无法捕获从该方法传播的异常.