| |
|
![]() |
vbs/VBScript DOS/BAT hta htc python perl 游戏相关 VBA 远程脚本 ColdFusion ruby专题 autoit seraphzone PowerShell linux shell Lua Golang Erlang 其它教程 CSS/HTML/Xhtml html5 CSS XML/XSLT Dreamweaver教程 经验交流 |
-> .NET新手区 -> 多线程编程学习笔记——任务并行库(三) -> 正文阅读 |
[.NET新手区]多线程编程学习笔记——任务并行库(三) |
接上文 多线程编程学习笔记——任务并行库(一) 接上文 多线程编程学习笔记——任务并行库(二) 六、 实现取消选项 本示例学习如何实现基于Task的异步操作进行取消流程,以及在任务真正运行前如何知道任务已经被取消。 1.代码如下: using System; using System.Collections.Generic; using System.ComponentModel; using System.Linq; using System.Text; using System.Threading; using System.Threading.Tasks; namespace ThreadTPLDemo { class Program { static void Main(string[] args) { Console.WriteLine(" 将Task中实现取消操作。。。"); var cts =new CancellationTokenSource(); var task1 = new Task<int>(() => RunTask("任务 1",10, cts.Token),cts.Token); Console.WriteLine(" ——task1 状态—{0}", task1.Status); cts.Cancel(); Console.WriteLine(" ——取消——task1 状态—{0}—",task1.Status); Console.WriteLine(" ——task1 在出错之前 取消了操作—"); //task1.Start(); cts = new CancellationTokenSource(); var task2 = new Task<int>(() => RunTask("任务 2", 10, cts.Token),cts.Token); task2.Start(); for (int i = 0; i < 5; i++) { Thread.Sleep(500); Console.WriteLine(" ——task2 状态—{0}", task2.Status); } cts.Cancel(); for (int i = 0; i < 5; i++) { Thread.Sleep(500); Console.WriteLine(" ——task2 状态—{0}", task2.Status); } Console.WriteLine(" ——任务Task 运行结果—{0}", task2.Result); Thread.Sleep(2000); Console.Read(); } private static int RunTask(string name,int seconds,CancellationToken token) { Console.WriteLine("Task {0} 运行在线程={1}中,是否在线程池 :{2}",name, 2.程序运行结果如下图。 ![]() 首先我们来看task1的创建代码,我们给底层任务传递一次取消标志,然后给任务的构造函数又传递了一次。 那为什么要传递两次取消标志呢? 因为如果在task实际启动之前取消它,则TPL的底层有责任处理这个取消操作。经过TPL底层处理过取消操作的task,如果再次启动,则会抛出异常。如下图。 ![]() 然后需要我们自己写代码处理取消操作,在取消操作之后,任务的状态仍然是RanToCompletion,从TPL来角度来讲,这个task已经完成。 七、 处理task中的异常 通过此示例我们学习如何在task中抛出不同情况的异常,以及如何获取这些异常信息。 1.程序代码如下: using System; using System.Collections.Generic; using System.ComponentModel; using System.Linq; using System.Text; using System.Threading; using System.Threading.Tasks; namespace ThreadTPLDemo { class Program { static void Main(string[] args) { Console.WriteLine(" 处理Task中的异常信息。。。。。"); try { var task1 = Task.Run(() => RunTask("任务 1", 2)); int result = task1.Result; Console.WriteLine(" ——task1 状态—{0}---值=={1}", task1.Status,result); } catch (Exception ex) { Console.WriteLine(" ——task1 错误信息—{0};innerException--{1}", ex.Message, 2.程序运行结果,如下图。 ![]() 当程序启动时,创建一个任务task1并尝试同步获取结果。Result属性的Get部分会使当前线程等待直到这个任务完成,并将异常传播给当前线程。在这种情况下,通过catch代码块可以很容易地捕捉异常,不过这个异常是封装异常。所以可以访问InnerException来获取异常信息。 Task2使用GetAwaiter与GetResult来获取任务结果。这种情况下,不需要封装异常,TPL会提取异常。如果底层只有一个task,一次只提取一个异常。 最后一个示例是两个任务(task3,task4)抛出异常的情况 。通过后续操作来处理异常,只有之前的任务完成之前有异常,这个后续操作才会被触发 。通过后续操作传递TaskContinuationOption.OnlyOrFaulted选项来实现 ,在抛出的异常中封装了两个异常。 |
.NET新手区 最新文章 |
将ZIP文件添加到程序集资源文件然后在运行时 |
Web服务的调用 |
.NET创建WebService服务简单的例子 |
多线程编程学习笔记——任务并行库(三) |
序列化和反序列化 |
Spring学习之路 |
多线程(2)Thread |
五小步让VS Code支持AngularJS智能提示 |
Log4net入门(SQL篇) |
C#十五子游戏 |
上一篇文章 下一篇文章 查看所有文章 |
|
360图书馆
软件开发
购物精选
智慧山
阅读网
日历
万年历
2021年4日历 2021/4/23 16:14:56 |
|
网站联系: qq:121756557 email:121756557@qq.com 编程知识 |