如果引发任何exception,如何在Task.WhenAll上取消并引发exception?

我正在使用Task.WhenAll等待倍数任务。 当其中一个生成exception时,我希望Task.WhenAll(或任何其他等待多个任务的方式)立即取消其他任务并引发exception。

可能吗?

提前致谢

取消是合作的当WhenAll无法取消线程,但你可以传递所有这些线程的CancellationToken并在你获得exception时触发令牌。

 CancellationTokenSource cts = new CancellationTokenSource(); var task1 = Func1Async(cts.Token); task1.ContinueWith(task => cts.Cancel(), cts.Token, TaskContinuationOptions.OnlyOnFaulted, TaskScheduler.Default); var task2 = Func2Async(cts.Token); task2.ContinueWith(task => cts.Cancel(), cts.Token, TaskContinuationOptions.OnlyOnFaulted, TaskScheduler.Default); var task3 = Func3Async(cts.Token); task3.ContinueWith(task => cts.Cancel(), cts.Token, TaskContinuationOptions.OnlyOnFaulted, TaskScheduler.Default); await Task.WhenAll(task1, task2, task3); 

从方法内部你需要在函数内部放置token.ThrowIfCancellationRequested()来检查令牌并取消任务

 public async Task Func1Async(CancellationToken token) { foreach(var item in GetItems1()) { await item.ProcessAsync(token); token.ThrowIfCancellationRequested(); } } 

注意:您可以通过制作扩展方法来稍微清理代码

 public static class ExtensionMethods { public Task CancelOnFaulted(this Task task, CancellationTokenSource cts) { task.ContinueWith(task => cts.Cancel(), cts.Token, taskContinuationOptions.OnlyOnFaulted, TaskScheduler.Default); return task; } public Task CancelOnFaulted(this Task task, CancellationTokenSource cts) { task.ContinueWith(task => cts.Cancel(), cts.Token, taskContinuationOptions.OnlyOnFaulted, TaskScheduler.Default); return task; } } 

这会使代码看起来像

 CancellationTokenSource cts = new CancellationTokenSource(); var task1 = Func1Async(cts.Token).CancelOnFaulted(cts); var task2 = Func2Async(cts.Token).CancelOnFaulted(cts); var task3 = Func3Async(cts.Token).CancelOnFaulted(cts); await Task.WhenAll(task1, task2, task3);