我有一个同步的方法,该方法,除其他事项外,检查挂起任务的状态,并重新抛出的异常,如果有的话:
无效测试(工作任务)
{
// ...
如果(task.IsFaulted)
扔task.Exception;
// ...
}
这不传播的异常堆栈跟踪信息,并调试程序不友好。
现在,如果测试
是异步
,它不会是简单和自然的,因为这样的:
异步任务测试(工作任务)
{
// ...
如果(task.IsFaulted)
等待任务; //立即正确地重新抛出
// ...
}
问:怎么做是正确的同步方法我想出了这一点,但我不喜欢它:?
无效测试(工作任务)
{
// ...
如果(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.