我有一个同步方法,除其他外,它检查挂起任务的状态并重新抛出其异常,如果有的话:
void Test(Task task)
{
// ...
if (task.IsFaulted)
throw task.Exception;
// ...
}
Run Code Online (Sandbox Code Playgroud)
这不会传播异常堆栈跟踪信息,并且对调试器不友好.
现在,如果Test是async,它将不会像这样简单和自然:
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) 我有一个返回任务的Async方法.
我也希望提供同步等效,但我不希望它的消费者必须去解包AggregateException.
现在我明白了整个想法是你不能随意选择一个,我知道我可以阅读更多的Stephen Toub文章(我会,但不是现在),我会理解这一切,并且可以自己决定.
在此期间,我想使用这样一个事实:我的任务实际上只是没有并行性的链接"工作流程",只是干预Waits(不,不是TPL DataFlow),这不应该导致多个异常.在这种情况下,处理如下是适当的:
CallAsync().Wait();
}
catch( AggregateException ae)
{
throw ae.Flatten().First()
Run Code Online (Sandbox Code Playgroud)
或者我保证即使有不止一个也AggregateException总是有InnerException.还是有一种情况我应该回归.Flatten().First()?
在一些TPL文档中,我看到了对Unwrap()方法的引用AggregateException(不确定它是否是扩展或beta版本中的某些内容).
作为占位符,我正在做:
void Call( )
{
try
{
CallAsync().Wait();
}
catch ( AggregateException ex )
{
var translated = ex.InnerException ?? ex.Flatten().InnerExceptions.First();
if ( translated == null )
throw;
throw translated; }
}
Task CallAsync(){ ...
Run Code Online (Sandbox Code Playgroud) asynchronous exception-handling task-parallel-library c#-4.0