[英]Wait for all tasks without throwing exceptions
如果我await Task.WhenAll(tasks)
它会在一项或多项任务失败时抛出异常。 我想手动检查每个任务对象。
通常catch(Exception)
不是一个好主意。 在这种情况下这样做是否合理? 或者也许有另一种方法来等待所有任务? 我无法捕获AggregateException
,因为如果只有一个,它将被解包。
如何在异步方法中正确地做到这一点?
下面的AwaitCompletion
扩展方法使用更通用的 API 满足您的要求。 它返回一个Task
,因此您仍然需要通过await
或Task.Wait()
或其他方式await
它。
using System.Collections.Generic;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;
public static class TaskExtensions
{
public static Task AwaitCompletion<T>(this ICollection<Task<T>> unfinishedTasks)
{
int remainingCount = unfinishedTasks.Count;
var promise = new TaskCompletionSource<ICollection<Task<T>>>();
var finishers = unfinishedTasks.Select(x => x.ContinueWith((task, state) =>
{
int postCount = Interlocked.Decrement(ref remainingCount);
if (postCount == 0)
{
promise.SetResult(unfinishedTasks);
}
}, remainingCount));
// force evaluation
var _ = finishers.ToList();
return promise.Task;
}
/// <summary>
/// Unlike Task.Value, this doesn't wait for completion. Hence, it also doesn't
/// throw exceptions.
/// </summary>
/// <returns>Value if completed, otherwise null (or default value if a value type)</returns>
public static T GetResultOrDefault<T>(this Task<T> self)
{
if (self.IsCompletedSuccessfully)
{
return self.Result;
}
else
{
return default(T);
}
}
}
完成返回的Task
值后, unfinishedTasks
所有任务要么完成要么出错(或者如果您使用Task.Wait()
超时,则仍然继续)。 AwaitCompletion
不会抛出异常,等待它只会在达到超时时抛出异常。 要检索异常,请查看您传入的任务。
用法:
Task[] tasksToWaitFor = ...
await tasksToWaitFor.AwaitCompletion()
foreach (var task in tasksToWaitFor)
{
Console.WriteLine("result: {}", task.GetResultOrDefault());
}
GetResultOrDefault
扩展方法很重要。 如果你直接点击Value
,它会在任务失败时抛出 AggregateException,OTOH GetResultOrDefault
将返回 null。
暂时吞下异常
await Task.WhenAll(tasks).ContinueWith(delegate {} )
但请记住,然后单独检查所有任务并正确显示错误。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.