转自: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 的实例就可以了。
