How to implement Task.WhenAny() with a predicate

前端 未结 5 1746
半阙折子戏
半阙折子戏 2020-12-06 21:03

I want to execute several asynchronous tasks concurrently. Each task will run an HTTP request that can either complete successfully or throw an exception. I need to aw

5条回答
  •  误落风尘
    2020-12-06 21:48

    Another way of doing this, very similar to Sir Rufo's answer, but using AsyncEnumerable and Ix.NET

    Implement a little helper method to stream any task as soon as it's completed:

    static IAsyncEnumerable> WhenCompleted(IEnumerable> source) =>
        AsyncEnumerable.Create(_ =>
        {
            var tasks = source.ToList();
            Task current = null;
            return AsyncEnumerator.Create(
                async () => tasks.Any() && tasks.Remove(current = await Task.WhenAny(tasks)), 
                () => current,
                async () => { });
        });
    }
    

    One can then process the tasks in completion order, e.g. returning the first matching one as requested:

    await WhenCompleted(tasks).FirstOrDefault(t => t.Status == TaskStatus.RanToCompletion)
    

提交回复
热议问题