sourabh devpura
sourabh devpura

Reputation: 625

How Task.WaitAll() Behave?

I have created a list of Task, like this:

public void A()
{

}

public void B()
{

}

public void C()
{

}

public void Ex()
{
   Task.WaitAll(Task.Factory.StartNew(A), Task.Factory.StartNew(B), Task.Factory.StartNew(C));
   var p=true;
}

Now my question is that. Will all the Tasks inside the list execute one by one or will they execute in parallel.

p=true

"p" is set when all tasks are done or before they are done?

Upvotes: 3

Views: 2326

Answers (2)

Fabio Salvalai
Fabio Salvalai

Reputation: 2509

For the first question:

Will those tasks execute one by one or asynchronously.

(here, I imagine you meant concurrently, which is not exactly the same)

Using StartNew will run your task in the current TaskScheduler. by default that means it will use the ThreadPool and, if there are any available slots in the thread pool, it will be run in parallel. If all slots are taken in the task pool, it may throttle the execution of the tasks in order to avoid the CPU to be overwhelmed, and the tasks may not be executed at the same concurrently: there are no guarantees.

This is a simplified explanation and a more complete and detailed explanation on the scheduling strategy is explained on the TaskScheduler documentation.

As a side note. The documentation for StartTask mentions a subtle difference between StartNew(Action) and Run(Action). They are not exactly equivalent, unlike stated in other answers.

Starting with the .NET Framework 4.5, you can use the Task.Run(Action) method as a quick way to call StartNew(Action) with default parameters. Note, however, that there is a difference in behavior between the two methods regarding : Task.Run(Action) by default does not allow child tasks started with the TaskCreationOptions.AttachedToParent option to attach to the current Task instance, whereas StartNew(Action) does.

For the second question

"p" is set when all tasks are done or before they are done?

The short answer is yes.

However, you should consider using another approach as this one will block your thread and waiting idly. The alternative is to give the control back to the caller if you can and so the thread is freed and can be used by the CPU. this is especially true if the thread on which this code is running is part of a ThreadPool.

therefore, you should prefer using WhenAll(). It returns a Task, which can be awaited or on which ContinueWith can be called

example:

var tasks = new Task[] {Task.Factory.StartNew(A), Task.Factory.StartNew(B), Task.Factory.StartNew(C)}; 
await Task.WhenAll(tasks);

Upvotes: 7

SHM
SHM

Reputation: 1952

first: you are creating the tasks in wrong way. when you instantiate a task you need to call Start method on it otherwise it dose nothing.

new Task(() => /* Something * /).Start();

if you create Tasks the way you just did (by calling constructor and hitting start or using the TaskFacotry or even Task.Run) by default a ThreadPool thread will be dedicated to the task and thus the task is executed in parallel.

the Task.WhenAll Method will block the execution of calling method until all tasks which are passed to it are done executing.

so the boolean variable is set after all tasks are done.

Upvotes: 2

Related Questions