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