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

2023-09-04 02:48:34 作者:风吹散的思念

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

 无效测试(工作任务)
{
    // ...
    如果(task.IsFaulted)
        扔task.Exception;
    // ...
}
 

这不传播的异常堆栈跟踪信息,并调试程序不友好。

现在,如果测试异步,它不会是简单和自然的,因为这样的:

 异步任务测试(工作任务)
{
    // ...
    如果(task.IsFaulted)
        等待任务; //立即正确地重新抛出
    // ...
}
 
解决在待办任务菜单中都会抛出异常,由于definitionId undefined导致的问题

问:怎么做是正确的同步方法我想出了这一点,但我不喜欢它:?

 无效测试(工作任务)
{
    // ...
    如果(task.IsFaulted)
        新的行动(异步()=>等待任务)();
    // ...
}
 

解决方案

要正确地重新抛出一个异常,你应该使用 ExceptionDispatchInfo

  ExceptionDispatchInfo.Capture(task.Exception.InnerException).Throw();
 

您的可以的也在做:

  task.GetAwaiter()调用getResult()。
 

P.S。你的动作办法将无法正常工作,因为你创建一个异步无效方法,你不能赶上传播异常从该方法。

I have a synchronous method which, amongst other things, checks the status of a pending task and rethrows its exception, if any:

void Test(Task task)
{
    // ...
    if (task.IsFaulted)
        throw task.Exception;
    // ...
}

This doesn't propagate the exception stack trace information and is debugger-unfriendly.

Now, if the Test was async, it would not be as simple and natural as this:

async Task Test(Task task)
{
    // ...
    if (task.IsFaulted)
        await task; // rethrow immediately and correctly
    // ...
}

Question: how to do it right for a synchronous method? I have come up with this but I do not like it:

void Test(Task task)
{
    // ...
    if (task.IsFaulted)
        new Action(async () => await task)();
    // ...
}

解决方案

To properly re-throw an exception, you should use ExceptionDispatchInfo:

ExceptionDispatchInfo.Capture(task.Exception.InnerException).Throw();

You can also do:

task.GetAwaiter().GetResult();

P.S. Your Action approach will not work correctly, since you're creating an async void method, and you cannot catch exceptions propagated from that method.