Await list of async predicates, but drop out on first false

后端 未结 6 891
孤街浪徒
孤街浪徒 2021-01-12 21:20

Imagine the following class:

public class Checker
{
   public async Task Check() { ... }
}

Now, imagine a list of instances of

6条回答
  •  南笙
    南笙 (楼主)
    2021-01-12 21:55

    Here's a fully functional test program, following in steps of dcastro:

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.Threading.Tasks;
    
    namespace AsyncCheckerTest
    {
        public class Checker
        {
            public int Seconds { get; private set; }
    
            public Checker(int seconds)
            {
                Seconds = seconds;
            }
    
            public async Task CheckAsync()
            {
                await Task.Delay(Seconds * 1000);
                return Seconds != 3;
            }
        }
    
        class Program
        {
            static void Main(string[] args)
            {
                var task = RunAsync();
                task.Wait();
    
                Console.WriteLine("Overall result: " + task.Result);
                Console.ReadLine();
            }
    
            public static async Task RunAsync()
            {
                var checkers = new List();
                checkers
                    .AddRange(Enumerable.Range(1, 5)
                    .Select(i => new Checker(i)));
    
                return await checkers
                                .Select(c => c.CheckAsync())
                                .AllAsync();
            }
        }
    
        public static class ExtensionMethods
        {
            public static async Task AllAsync(this IEnumerable> source)
            {
                var tasks = source.ToList();
    
                while (tasks.Count != 0)
                {
                    Task finishedTask = await Task.WhenAny(tasks);
    
                    bool checkResult = finishedTask.Result;
    
                    if (!checkResult)
                    {
                        Console.WriteLine("Completed at " + DateTimeOffset.Now + "...false");
                        return false;
                    }
    
                    Console.WriteLine("Working... " + DateTimeOffset.Now);
                    tasks.Remove(finishedTask);
                }
    
                return true;
            }
        }
    }
    

    Here's sample output:

    Working... 6/27/2014 1:47:35 AM -05:00
    Working... 6/27/2014 1:47:36 AM -05:00
    Completed at 6/27/2014 1:47:37 AM -05:00...false
    Overall result: False
    

    Note that entire eval ended when exit condition was reached, without waiting for the rest to finish.

提交回复
热议问题