zoukankan      html  css  js  c++  java
  • 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("
    Task 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("
    AggregateException 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
  • 相关阅读:
    sockjs-node/info 请求错误
    vue项目中 —— rem布局适配方案
    JS判断对象是否为空
    JS生成一个特定格式随机数
    vue项目中axios请求网络接口封装
    vue报错——error Unexpected console statement no-console
    vue切换页面修改网页的标题
    处理js两个数相乘的坑
    js科学计数法问题
    (9)kendo UI使用基础介绍与问题整理——Validator/基础说明、实例介绍
  • 原文地址:https://www.cnblogs.com/rock_chen/p/3286262.html
Copyright © 2011-2022 走看看