1

I need to wait for one or more tasks to complete. The number of tasks that I need to wait on depends upon a few conditions. So my code is something like below.

Task[] tasks = new Task[2];

if (condition1 == true)
{
    tasks[0] = Task.Factory.StartNew(() => MyMethod1());
}

if (condition2 == true)
{
    tasks[1] = Task.Factory.StartNew(() => MyMethod2());
}

Task.WaitAll(tasks);

Let's say condition2 is false, so there is only one item in the tasks array. Will the WaitAll only wait for tasks[0] in this case?

Michael Liu
  • 52,147
  • 13
  • 117
  • 150
whoami
  • 1,689
  • 3
  • 22
  • 45

2 Answers2

2

Both Task.WaitAll and Task.WhenAll throw ArgumentException if any element of the tasks array is null.

To avoid the exception, you can add your tasks to a List<Task> instead:

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

if (condition1)
{
    tasks.Add(Task.Factory.StartNew(() => MyMethod1()));
}

if (condition2)
{
    tasks.Add(Task.Factory.StartNew(() => MyMethod2()));
}

Task.WaitAll(tasks.ToArray());
Michael Liu
  • 52,147
  • 13
  • 117
  • 150
  • 2
    One should not really be using `WaitAll` (instead of `WhenAll` with proper `async`/`await`), but indeed this is the right answer as OP asked. – Alexei Levenkov Jun 20 '15 at 19:28
0

It is better to use WhenAll which supports IEnumerable as parameter. This allows you to use a different container than an array and will avoid the exception in the first place.

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

if (condition1)
{
    tasks.Add(Task.Factory.StartNew(() => MyMethod1()));
}

if (condition2)
{ 
    tasks.Add(Task.Factory.StartNew(() => MyMethod2()));
}

await Task.WhenAll(tasks);

See also WaitAll vs WhenAll

Community
  • 1
  • 1
Philip Stuyck
  • 7,344
  • 3
  • 28
  • 39