最近刚装上了vs2012,发现新增加Task任务,很不错,应该是Thread有一定的优势,特别是UI相关的多线程方面,可以很方便实现,不让界面死锁掉。
但在中断时遇到问题:
为什么取消的Task实际偷偷的还在继续运行呢?
首先如何中断,我们会使用到CancellationTokenSource这个,很容易做到。
1 static void Main(string[] args) 2 { 3 try 4 { 5 Run(); 6 } 7 catch (OperationCanceledException) 8 { 9 Console.WriteLine("OperationCanceledException:操作取消了."); 10 } 11 12 13 Thread.Sleep(1000 * 300);//等待结束。 14 } 15 16 17 18 19 static async void Run() 20 { 21 Console.WriteLine("Run2开始."); 22 //主要的任务 23 Task tw = new Task(() => 24 { 25 26 //这是可以中断或取消任务的 27 CancellationTokenSource tokenSource = new CancellationTokenSource(); 28 var token = tokenSource.Token; 29 30 31 //这个是实际想完成的任务 32 Task t1 = Task.Factory.StartNew(() => 33 { 34 //异步执行 35 Task.Factory.StartNew(() => 36 { 37 TaskTest1(); 38 }); 39 40 41 while (true) 42 { 43 //检测到取消了 44 if (token.IsCancellationRequested) 45 { 46 Console.WriteLine("强制取消了"); 47 token.ThrowIfCancellationRequested();//强制取消 并不会让TaskTest1停止执行 48 } 49 Thread.Sleep(10); 50 } 51 52 53 54 }, token); 55 56 if (!t1.Wait(1000 * 5, tokenSource.Token))//这里设置了一个超时的时间秒数 57 { 58 tokenSource.Cancel();//取消任务 59 Console.WriteLine("超时,取消任务"); 60 } 61 62 63 }); 64 tw.Start();//任务开始了 65 await tw;//用这个,不会阻塞界面 66 Console.WriteLine("Run2结束."); 67 } 68 69 static void TaskTest1() 70 { 71 Console.WriteLine("TaskTest1 开始."); 72 Thread.Sleep(1000 * 20); 73 Console.WriteLine("TaskTest1 完成."); 74 }
输出:
1 Run2开始. 2 TaskTest1 开始. 3 超时,取消任务 4 Run2结束. 5 强制取消了 6 TaskTest1 完成.
取消了,但并代表任务中代码不执行下去了,从结果中发现,TaskTest1还在继续扩行,并且在20秒后,输出“TaskTest1 完成“。
Task有取消实际上是一个很简单取消,是一个状态的传入,需我们自己去取消任务,也就是TaskTest1中比如是读数据库,或是其它什么占用时间较长的,还有什么方法来取消呢?
欢迎大家一起交流!
Task是个很不错的,和async 、 await 可以很方便在UI下实现,不锁界面的,程序自己在后台执行。