Search code examples
c#async-awaittasktpl-dataflow

Task.WhenAll doesn't resume


Below code is simplified version what i am trying to do. The code supposed to reach Console.ReadKey() line very quickly but it never happens. Task.WhenAll never resume next line. What is wrong on the code ?

class Program
{
    static void Main(string[] args)
    {
        DoWorkAsync().Wait();
        Console.ReadKey();
    }

    static async Task DoWorkAsync()
    {
        var block = new ActionBlock<Job>(async (task) =>
        {
            await task.DoAsync();
        });
        var jobs = Enumerable.Range(0, 2).Select(i => new Job());
        foreach (var job in jobs)
        {
            await block.SendAsync(job);
        }
        await Task.WhenAll(jobs.Select(c => c.Completion));
    }

    public class Job
    {
        TaskCompletionSource<bool> completionSource = new TaskCompletionSource<bool>();
        public Task<bool> Completion { get { return completionSource.Task; } }
        public async Task DoAsync()
        {
            await Task.Delay(100);
            completionSource.SetResult(true);
        }
    }

Solution

  • It will help.

    var jobs = Enumerable.Range(0, 2).Select(i => new Job()).ToList();
    

    It happens because of multiple enumeration of jobs

    In this line await Task.WhenAll(jobs.Select(c => c.Completion)); you are waiting for new jobs, which are not send to block.