Export (0) Print
Expand All
Expand Minimize

TaskFactory.ContinueWhenAll Method (Task[], Action<Task[]>)

Creates a continuation task that starts when a set of specified tasks has completed.

Namespace:  System.Threading.Tasks
Assemblies:   mscorlib (in mscorlib.dll)
  System.Threading.Tasks (in System.Threading.Tasks.dll)

public Task ContinueWhenAll(
	Task[] tasks,
	Action<Task[]> continuationAction


Type: System.Threading.Tasks.Task[]

The array of tasks from which to continue.

Type: System.Action<Task[]>

The action delegate to execute when all tasks in the tasks array have completed.

Return Value

Type: System.Threading.Tasks.Task
The new continuation task.


An element in the tasks array has been disposed.


The tasks array is null.


The continuationAction argument is null.


The tasks array is empty or contains a null value.

The ContinueWhenAll method executes the continuationAction delegate when all tasks in the tasks array have completed, regardless of their completion status.

Exceptions thrown by tasks in the tasks array are not available to the continuation task through structured exception handling. You can determine which exceptions were thrown by examining the Task.Exception property of each task in the tasks array. To use structured exception handling to handle exceptions thrown by tasks in the tasks array, call the Task.WaitAll(Task[]) method.

The following example launches separate tasks that use a regular expression to count the number of words in a set of text files. The ContinueWhenAll method is used to launch a task that displays the total word count when all the antecedent tasks have completed.

using System;
using System.Collections.Generic;
using System.IO;
using System.Threading;
using System.Threading.Tasks;
using System.Text.RegularExpressions;

public class Example
   public static void Main()
      string[] filenames = { "chapter1.txt", "chapter2.txt", 
                             "chapter3.txt", "chapter4.txt",
                             "chapter5.txt" };
      string pattern = @"\b\w+\b";
      var tasks = new List<Task>();  
      int totalWords = 0;

      // Determine the number of words in each file. 
      foreach (var filename in filenames) 
         tasks.Add( Task.Factory.StartNew( fn => { if (! File.Exists(fn.ToString()))
                                                      throw new FileNotFoundException("{0} does not exist.", filename);

                                                   StreamReader sr = new StreamReader(fn.ToString());
                                                   String content = sr.ReadToEnd();
                                                   int words = Regex.Matches(content, pattern).Count;
                                                   Interlocked.Add(ref totalWords, words); 
                                                   Console.WriteLine("{0,-25} {1,6:N0} words", fn, words); }, 

      var finalTask = Task.Factory.ContinueWhenAll(tasks.ToArray(), wordCountTasks => {
                                                    int nSuccessfulTasks = 0;
                                                    int nFailed = 0;
                                                    int nFileNotFound = 0;
                                                    foreach (var t in wordCountTasks) {
                                                       if (t.Status == TaskStatus.RanToCompletion) 

                                                       if (t.Status == TaskStatus.Faulted) {
                                                          t.Exception.Handle( (e) => { 
                                                             if (e is FileNotFoundException)
                                                             return true;   
                                                    Console.WriteLine("\n{0,-25} {1,6} total words\n", 
                                                                      String.Format("{0} files", nSuccessfulTasks), 
                                                    if (nFailed > 0) {
                                                       Console.WriteLine("{0} tasks failed for the following reasons:", nFailed);
                                                       Console.WriteLine("   File not found:    {0}", nFileNotFound);
                                                       if (nFailed != nFileNotFound)
                                                          Console.WriteLine("   Other:          {0}", nFailed - nFileNotFound);
// The example displays output like the following: 
//       chapter2.txt               1,585 words 
//       chapter1.txt               4,012 words 
//       chapter5.txt               4,660 words 
//       chapter3.txt               7,481 words 
//       4 files                    17738 total words 
//       1 tasks failed for the following reasons: 
//          File not found:    1

The call to the continuation task's Task.Wait method does not allow it to handle exceptions thrown by the antecedent tasks, so the example examines the Task.Status property of each antecedent task to determine whether the task succeeded.

.NET Framework

Supported in: 4.6, 4.5, 4

.NET Framework Client Profile

Supported in: 4

Portable Class Library

Supported in: Portable Class Library

.NET for Windows Store apps

Supported in: Windows 8

Supported in: Windows Phone 8.1

Supported in: Windows Phone Silverlight 8.1

Supported in: Windows Phone Silverlight 8

Windows Phone 8.1, Windows Phone 8, Windows 8.1, Windows Server 2012 R2, Windows 8, Windows Server 2012, Windows 7, Windows Vista SP2, Windows Server 2008 (Server Core Role not supported), Windows Server 2008 R2 (Server Core Role supported with SP1 or later; Itanium not supported)

The .NET Framework does not support all versions of every platform. For a list of the supported versions, see .NET Framework System Requirements.

© 2014 Microsoft