C# .Net并行(多核)编程 3 - Task的基本用法(取消Task的执行)


转自:http://ggicci.blog.163.com/blog/static/210364096201272034821778/

Title :

  • Pro .NET 4 Parallel Programming in C# (Adam Freeman) Task的基本用法
  • Task 的取消

 

Steps :

 

C .Net并行(多核)编程 3 - Task的基本用法(取消Task的执行) - ___________杰 - G  G  I  C  C  I
 

Quote :

You must also throw an instance of System.Threading.OperationCanceledException in your task body; this is how you acknowledge the cancellation, and if you forget, the status of your task will not be set correctly. [ From “Pro .Net 4 Parallel Programming in C#”]

你必须在你的Task的执行体里面抛出一个System.Threading.OperationCanceledException异常。具体有两种形式 :

    1.    1: while(true) {
         2:     if(token.IsCancellationRequested) {
         3:         throw new OperationCanceledException(token);
         4:     } else {
         5:         //do your work
         6:     }
         7: }
       
    2.    1: while(true) {
         2:     token.ThrowIfCancellationRequested();
         3:     //do your work
         4: }

Simple Sample :

   1: using System;
   2: using System.Threading;
   3: using System.Threading.Tasks;
   4:  
   5: namespace Parallel_TaskProgramming
   6: {
   7:     class Program
   8:     {
   9:         public static void Main(string[] args)
  10:         {
  11:             //step 1: create a instance of System.Threading.CancellationTokenSource
  12:             CancellationTokenSource tokenSource = new CancellationTokenSource();
  13:             //step 2: call the CancellationTokenSource.Token property to get a System.Threading.CancellationToken
  14:             CancellationToken token = tokenSource.Token;
  15:             
  16:             //step 3: create a new Task or Task<T>
  17:             Task task = new Task(() => {
  18:                 int i = 0;
  19:                 while (true)
  20:                 {
  21:                     token.ThrowIfCancellationRequested();
  22:                     Console.WriteLine(i++);
  23:                 }                
  24:             }, token);
  25:         
  26:             //step 4: start the task and then you can call CancellationTokenSource.Cancel() to cancel the task
  27:             task.Start();
  28:             //主线程睡眠 5 ms
  29:             Thread.Sleep(5);
  30:             tokenSource.Cancel();
  31:             
  32:             Console.WriteLine("Press enter to finish.");
  33:             Console.ReadLine();
  34:         }
  35:     }
  36: }
Result : 结果是不确定的,5 ms 能打印多少次数字取决于运行时 CPU 的忙碌程度
   1: 0
   2: 1
   3: 2
   4: 3
   5: 4
   6: 5
   7: 6
   8: 7
   9: 8
  10: 9
  11: 10
  12: 11
  13: 12
  14: Press enter to finish.

Register : Monitoring Cancellation with a Delegate

CancellationToken 的 Register 方法可以为 token 登记一个 Action 或 Action<Object> 委托(代理)的实例。当 Task 被取消执行后,这个委托会被执行。

在上面 Simple Sample 的代码中的 task.Start() 前加上如下代码:

   1: token.Register(() =>
   2: {
   3:     Console.WriteLine("Task was canceled and then I'm invoked.");
   4: });

Result :

   1: 0
   2: 1
   3: 2
   4: 3
   5: 4
   6: Task was canceled and then I'm invoked.
   7: Press enter to finish.

WaitHandle : Monitoring Cancellation with a Wait Handle

CancellationToken 有个 WaitHandle 属性,这个属性是一个 WaitHandle 类的对象,WaitHandle 类的 WaitOne 方法的作用是:阻塞当前线程,直到当前的 WaitHandle 接收到一个信号。

Sample :

   1: public static void Main(string[] args)
   2: {
   3:     CancellationTokenSource tokenSource = new CancellationTokenSource();
   4:     CancellationToken token = tokenSource.Token;
   5:  
   6:     Task task = new Task(() =>
   7:     {
   8:         Console.WriteLine("Task running...");
   9:         token.WaitHandle.WaitOne();
  10:         Console.WriteLine("Hello");
  11:     }, token);
  12:  
  13:     Console.WriteLine("Press enter to cancel the task.");
  14:     task.Start();
  15:     
  16:     //按空格键取消任务
  17:     Console.ReadLine();
  18:     tokenSource.Cancel();
  19:  
  20:     Console.WriteLine("Press enter to finish.");
  21:     Console.ReadLine();
  22: }

Result :

   1: Press enter to cancel the task.
   2: Task running...
   3:  
   4: Hello
   5: Press enter to finish.

Canceling Several Tasks : 取消多个任务

很简单,只需要在创建任务的时候用同一个 CancallationToken 的实例就可以了。


免责声明!

本站转载的文章为个人学习借鉴使用,本站对版权不负任何法律责任。如果侵犯了您的隐私权益,请联系本站邮箱yoyou2525@163.com删除。



 
粤ICP备18138465号  © 2018-2025 CODEPRJ.COM