相关疑难解决方法(0)

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

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

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)

.net c# task-parallel-library async-await

7
推荐指数
1
解决办法
4065
查看次数

根据非并行任务(转换/解包AggregateExceptions)实现同步方法的模式

我有一个返回任务的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

6
推荐指数
1
解决办法
1801
查看次数