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