轉自:http://ggicci.blog.163.com/blog/static/210364096201272034821778/
Title :
- Pro .NET 4 Parallel Programming in C# (Adam Freeman) Task的基本用法
- Task 的取消
Steps :
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: while(true) {
2: if(token.IsCancellationRequested) {
3: throw new OperationCanceledException(token);
4: } else {
5: //do your work
6: }7: } -
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_TaskProgramming6: {7: class Program8: {9: public static void Main(string[] args)10: {11: //step 1: create a instance of System.Threading.CancellationTokenSource12: CancellationTokenSource tokenSource = new CancellationTokenSource();13: //step 2: call the CancellationTokenSource.Token property to get a System.Threading.CancellationToken14: 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 task27: task.Start();28: //主線程睡眠 5 ms29: Thread.Sleep(5);30: tokenSource.Cancel();31:32: Console.WriteLine("Press enter to finish.");33: Console.ReadLine();34: }35: }36: }
1: 02: 13: 24: 35: 46: 57: 68: 79: 810: 911: 1012: 1113: 1214: 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: 02: 13: 24: 35: 46: 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: Hello5: Press enter to finish.
Canceling Several Tasks : 取消多個任務
很簡單,只需要在創建任務的時候用同一個 CancallationToken 的實例就可以了。
