Is it possible to get successful results from a Task.WhenAll when one of the tasks fails?

后端 未结 4 682
陌清茗
陌清茗 2021-01-03 10:22

Given the following:

var tPass1 = Task.FromResult(1);
var tFail1 = Task.FromException(new ArgumentException(\"fail1\"));
var tFail2 = Task.FromExc         


        
4条回答
  •  梦谈多话
    2021-01-03 10:49

    Playing around with @Theodor Zoulias's powerfull and elegant solution pushed me to something. It looks hacky, but still works. One can continue Task.WhenAll with something that will not throw an exception for sure (e.g. _ => { }) and Wait that something.

    var cts = new CancellationTokenSource();
    cts.Cancel();
    var canceled = Task.Run(() => 1, cts.Token);
    
    var faulted = Task.FromException(new Exception("Some Exception"));
    
    var ranToCompletion = Task.FromResult(1);
    
    var allTasks = new[] { canceled, faulted, ranToCompletion };
    
    // wait all tasks to complete regardless anything
    Task.WhenAll(allTasks).ContinueWith(_ => { }).Wait();
    
    foreach(var t in allTasks)
    {
        Console.WriteLine($"Task #{t.Id} {t.Status}");
        if (t.Status == TaskStatus.Faulted)
            foreach (var e in t.Exception.InnerExceptions)
                Console.WriteLine($"\t{e.Message}");
        if (t.Status == TaskStatus.RanToCompletion)
            Console.WriteLine($"\tResult: {t.Result}");
    }
    

    Output looks like this:

    Task #2 Canceled
    Task #1 Faulted
            Some Exception
    Task #5 RanToCompletion
            Result: 1
    

提交回复
热议问题