相关疑难解决方法(0)

为什么不等待Task.WhenAll抛出AggregateException?

在这段代码中:

private async void button1_Click(object sender, EventArgs e) {
    try {
        await Task.WhenAll(DoLongThingAsyncEx1(), DoLongThingAsyncEx2());
    }
    catch (Exception ex) {
        // Expect AggregateException, but got InvalidTimeZoneException
    }
}

Task DoLongThingAsyncEx1() {
    return Task.Run(() => { throw new InvalidTimeZoneException(); });
}

Task DoLongThingAsyncEx2() {
    return Task.Run(() => { throw new InvalidOperation();});
}
Run Code Online (Sandbox Code Playgroud)

我期望WhenAll创建并抛出一个AggregateException,因为至少有一个等待抛出异常的任务.相反,我正在收回其中一个任务抛出的单个异常.

难道WhenAll不总是创造AggregateException

.net asynchronous exception tap

83
推荐指数
6
解决办法
3万
查看次数

如何等待一系列任务并停止等待第一个异常?

我有一系列任务,正在等他们Task.WhenAll。我的任务经常失败,在这种情况下,我会向用户显示一个消息框,以便她可以重试。我的问题是报告错误的时间延迟到所有任务完成为止。相反,我想在第一个任务抛出异常后立即通知用户。换句话说,我希望该版本Task.WhenAll能够快速失败。由于不存在这样的内置方法,因此我尝试创建自己的方法,但是我的实现未达到我想要的方式。这是我想出的:

public static async Task<TResult[]> WhenAllFailFast<TResult>(
    params Task<TResult>[] tasks)
{
    foreach (var task in tasks)
    {
        await task.ConfigureAwait(false);
    }
    return await Task.WhenAll(tasks).ConfigureAwait(false);
}
Run Code Online (Sandbox Code Playgroud)

通常,它的抛出速度比本机快Task.WhenAll,但通常不够快。在任务#1完成之前将不会观察到有故障的任务#2。我如何改进它以使其尽快失效?


更新:关于取消,这不是我现在的要求,但是可以说,为了保持一致,第一个被取消的任务应立即停止等待。在这种情况下,从返回的合并任务WhenAllFailFast应具有Status == TaskStatus.Canceled

说明:取消方案是关于用户单击“ 取消”按钮以阻止任务完成。它不是要在发生异常时自动取消未完成的任务。

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

5
推荐指数
2
解决办法
153
查看次数