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 }