How to: Cancel a Task and Its Children
http://msdn.microsoft.com/en-us/library/dd537607.aspx
using System; using System.Collections.Concurrent; using System.Threading; using System.Threading.Tasks; public class Example { public static void Main() { var tokenSource = new CancellationTokenSource(); var token = tokenSource.Token; // Store references to the tasks so that we can wait on them and // observe their status after cancellation. Task t; var tasks = new ConcurrentBag<Task>(); Console.WriteLine("Press any key to begin tasks..."); Console.WriteLine("To terminate the example, press 'c' to cancel and exit..."); Console.ReadKey(); Console.WriteLine(); // Request cancellation of a single task when the token source is canceled. // Pass the token to the user delegate, and also to the task so it can // handle the exception correctly. t = Task.Factory.StartNew( () => DoSomeWork(1, token), token); Console.WriteLine("Task {0} executing", t.Id); tasks.Add(t); // Request cancellation of a task and its children. Note the token is passed // to (1) the user delegate and (2) as the second argument to StartNew, so // that the task instance can correctly handle the OperationCanceledException. t = Task.Factory.StartNew( () => { // Create some cancelable child tasks. Task tc; for (int i = 3; i <= 10; i++) { // For each child task, pass the same token // to each user delegate and to StartNew. tc = Task.Factory.StartNew( iteration => DoSomeWork((int)iteration, token), i, token); Console.WriteLine("Task {0} executing", tc.Id); tasks.Add(tc); // Pass the same token again to do work on the parent task. // All will be signaled by the call to tokenSource.Cancel below. DoSomeWork(2, token); } }, token); Console.WriteLine("Task {0} executing", t.Id); tasks.Add(t); // Request cancellation from the UI thread. if (Console.ReadKey().KeyChar == 'c') { tokenSource.Cancel(); Console.WriteLine("\nTask cancellation requested."); // Optional: Observe the change in the Status property on the task. // It is not necessary to wait on tasks that have canceled. However, // if you do wait, you must enclose the call in a try-catch block to // catch the TaskCanceledExceptions that are thrown. If you do // not wait, no exception is thrown if the token that was passed to the // StartNew method is the same token that requested the cancellation. } try { Task.WaitAll(tasks.ToArray()); } catch (AggregateException e) { Console.WriteLine("\nAggregateException thrown with the following inner exceptions:"); // Display information about each exception. foreach (var v in e.InnerExceptions) { if (v is TaskCanceledException) Console.WriteLine(" TaskCanceledException: Task {0}", ((TaskCanceledException) v).Task.Id); else Console.WriteLine(" Exception: {0}", v.GetType().Name); } Console.WriteLine(); } // Display status of all tasks. foreach (var task in tasks) Console.WriteLine("Task {0} status is now {1}", task.Id, task.Status); } static void DoSomeWork(int taskNum, CancellationToken ct) { // Was cancellation already requested? if (ct.IsCancellationRequested == true) { Console.WriteLine("Task {0} was cancelled before it got started.", taskNum); ct.ThrowIfCancellationRequested(); } int maxIterations = 100; // NOTE!!! A "TaskCanceledException was unhandled // by user code" error will be raised here if "Just My Code" // is enabled on your computer. On Express editions JMC is // enabled and cannot be disabled. The exception is benign. // Just press F5 to continue executing your code. for (int i = 0; i <= maxIterations; i++) { // Do a bit of work. Not too much. var sw = new SpinWait(); for (int j = 0; j <= 100; j++) sw.SpinOnce(); if (ct.IsCancellationRequested) { Console.WriteLine("Task {0} cancelled", taskNum); ct.ThrowIfCancellationRequested(); } } } } // The example displays output like the following: // Press any key to begin tasks... // To terminate the example, press 'c' to cancel and exit... // // Task 1 executing // Task 2 executing // Task 3 executing // Task 4 executing // Task 5 executing // Task 6 executing // Task 7 executing // Task 8 executing // c // Task cancellation requested. // Task 2 cancelled // Task 7 cancelled // // AggregateException thrown with the following inner exceptions: // TaskCanceledException: Task 2 // TaskCanceledException: Task 8 // TaskCanceledException: Task 7 // // Task 2 status is now Canceled // Task 1 status is now RanToCompletion // Task 8 status is now Canceled // Task 7 status is now Canceled // Task 6 status is now RanToCompletion // Task 5 status is now RanToCompletion // Task 4 status is now RanToCompletion // Task 3 status is now RanToCompletion
-----------------------------------
http://www.cnblogs.com/rock_chen/