[英]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.