簡體   English   中英

等待所有任務不拋出異常

[英]Wait for all tasks without throwing exceptions

如果我await Task.WhenAll(tasks)它會在一項或多項任務失敗時拋出異常。 我想手動檢查每個任務對象。

通常catch(Exception)不是一個好主意。 在這種情況下這樣做是否合理? 或者也許有另一種方法來等待所有任務? 我無法捕獲AggregateException ,因為如果只有一個,它將被解包。

如何在異步方法中正確地做到這一點?

下面的AwaitCompletion擴展方法使用更通用的 API 滿足您的要求。 它返回一個Task ,因此您仍然需要通過awaitTask.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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM