Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to add a task to the collection that Task.WhenAll is waiting for?

Isn't it possible to add a task to the list that Task.WhenAll is waiting already?

I want to wait for all the tasks to finish, and there is a possibility to create new tasks after initialization. But here Task.WhenAll doesn't wait for the new task that is added to the collection later.

List<Task> tasks = new List<Task>();

var task1 = Task.Run(async () =>
    {
        Debug.WriteLine("task #1 started");
        await Task.Delay(TimeSpan.FromSeconds(20));
        Debug.WriteLine("task #1 finished");
    });

var task2 = Task.Run(async () =>
{
    Debug.WriteLine("task #2 started");
    await Task.Delay(TimeSpan.FromSeconds(30));
    Debug.WriteLine("task #2 finished");
});

var task3 = Task.Run(async () =>
{
    Debug.WriteLine("task #3 started");
    await Task.Delay(TimeSpan.FromSeconds(10));
    var inner = Task.Run(async () =>
    {
        Debug.WriteLine("inner task started");
        await Task.Delay(TimeSpan.FromSeconds(40));
        Debug.WriteLine("inner task finished");
    });

    tasks.Add(inner);

    Debug.WriteLine("task #3 finished");
});

tasks.Add(task1);
tasks.Add(task2);
tasks.Add(task3);

await Task.WhenAll(tasks);
Debug.WriteLine("All finished");

Output:

task #2 started
task #3 started
task #1 started
task #3 finished
inner task started
task #1 finished
task #2 finished
All finished
inner task finished < didn't wait for this to finish
like image 720
Blendester Avatar asked Jan 16 '17 07:01

Blendester


People also ask

Does task WhenAll start the tasks?

WhenAll starts both Tasks at the same time and executes them in parallel, the outcome is that instead of taking 3 seconds to run the program it just takes 2 seconds, that's a huge performance enhancement!

What is await task WhenAll?

Running asynchronously – the faster way Instead of running each method and waiting for it to complete before starting the next one, I can start them all together and await the Task. WhenAll method to make sure all methods are completed before proceeding to the rest of the program.

What is the difference between task WaitAll and task WhenAll?

Task. WaitAll blocks the current thread until everything has completed. Task. WhenAll returns a task which represents the action of waiting until everything has completed.

How does task Wait work?

Wait is a synchronization method that causes the calling thread to wait until the current task has completed. If the current task has not started execution, the Wait method attempts to remove the task from the scheduler and execute it inline on the current thread.


1 Answers

This is because tasks.Add(inner) is executed after await Task.WhenAll(tasks). To answer your question, first you need to clearify the releationship between task #3 and task inner. IMO the inner task should be part of task #3. That is, task #3 can't finish until the inner task finishes.

await inner;   //instead of tasks.Add(inner);   
like image 160
Cheng Chen Avatar answered Nov 15 '22 00:11

Cheng Chen