1 /// <summary>
2 /// 任务扩展,传入取消操作
3 /// </summary>
4 public static class TaskExtensionDemo
5 {
6 //因为没有非泛型的TaskCompleteSource类
7 private struct Void { }
8
9 public static async Task<TResult> WithCancellation<TResult>(this Task<TResult> originalTask, CancellationToken cancellationToken)
10 {
11 var cancelTask = new TaskCompletionSource<Void>();
12
13 // 注册一个将在取消此 System.Threading.CancellationToken 时调用的委托。
14 using (cancellationToken.Register(t => ((TaskCompletionSource<Void>)t).TrySetResult(new Void()), cancelTask))
15 {
16 Task any = await Task.WhenAny(originalTask, cancelTask.Task);
17
18 if (any == cancelTask.Task)
19 {
20 cancellationToken.ThrowIfCancellationRequested();
21 }
22 }
23
24 return await originalTask;
25 }
26
27 public static async Task Go()
28 {
29 //在指定的延迟(以毫秒为单位)后将被取消。
30 var cts = new CancellationTokenSource(5000);
31 var ct = cts.Token;
32
33 try
34 {
35 Task<Int64> t = new Task<Int64>(() =>
36 {
37 //Task.Delay不阻塞线程,任务不会被取消(5秒后早执行完了)
38 //Task.Delay(10000);
39
40 //阻塞线程,10秒后收到取消通知
41 Thread.Sleep(10000);
42 return 0;
43 });
44 t.Start();
45
46 //调用扩展方法取消任务
47 await t.WithCancellation(ct);
48
49 Console.WriteLine("Task completed");
50 }
51 catch (OperationCanceledException)
52 {
53 Console.WriteLine("Task cancelled");
54 }
55 }
56 }