Task的一些用法总结
2018-06-17 20:00:47来源:未知 阅读 ()
一、Task和多线程以及异常的捕获示例代码:
static void Main(string[] args) { // 产生CancellationToken的类,该类允许使用Cancel方法终止线程 // 也可以使用CancellationTokenSource.CreateLinkedTokenSource创建 // 一组相关的Token,任意一个取消都取消 CancellationTokenSource ts = new CancellationTokenSource(); CancellationToken ct = ts.Token; Task t = null; t = new Task(() => { for (int i = 1; i < 11; i++) { // 调用Cancel方法,状态为true(表示已经取消了) if (!ts.IsCancellationRequested) { if (i == 5) { // 该异常不会直接被主线程捕获 throw new Exception("数字是5,非法!"); } } else { Console.WriteLine("用户取消"); // 抛出异常,强制取消子线程 ct.ThrowIfCancellationRequested(); } Console.WriteLine(i); Thread.Sleep(500); } }, ct); t.Start(); // 注册Cancel之后的引发的事件,注意Exception也可以在这里捕获 t.ContinueWith((task) => { // 只有调用Cancel方法才会被设置为True Console.WriteLine(t.IsCanceled); // 无论何种情况,只要完成了就是True Console.WriteLine(t.IsCompleted); // 只要有异常,为True(哪怕是ThrowIfCancellationRequested异常) Console.WriteLine(t.IsFaulted); // 捕获各种各样的异常 foreach (var item in task.Exception.InnerExceptions) { Console.WriteLine(item.Message); } }); Console.ReadLine(); // 取消任务 ts.Cancel(); Thread.Sleep(Timeout.Infinite); }
结论:
1、无论任何异常都会终止子线程。
2、异常发生之后,只有在Task的Wait/WaitAll/WaitAny/Result或者Continue方法才可以捕获异常,主线程不可能,因为是子线程中的异常。
二、Task的任务先后顺序(允许嵌套任务),同时允许把线程挂接到主线程上执行返回结果(避免以前Thread和WinForm控件交互时候发生的“不是由本线程创建的控件异常……”问题):
static void Main(string[] args) { CancellationTokenSource cts = new CancellationTokenSource(); CancellationToken ct = cts.Token; Task t = new Task(() => { Console.WriteLine("主任务开始……,包含3个子任务:"); Task.Factory.StartNew(() => { Thread.Sleep(2000); Console.WriteLine("任务一"); }, // 挂接到主线程,这样主线程会自动等待子线程完成后完成 TaskCreationOptions.AttachedToParent ); Task.Factory.StartNew(() => { Thread.Sleep(500); Console.WriteLine("任务二"); }, TaskCreationOptions.AttachedToParent); Task.Factory.StartNew(() => { Thread.Sleep(1000); Console.WriteLine("任务三"); }, TaskCreationOptions.AttachedToParent); }, ct); t.ContinueWith((Task) => { Console.WriteLine("子任务都完成,主任务结束。"); // 指定上下文的同步块,防止跨线程访问控件的问题(控制台程序不能使用,WinForm啥可以) },TaskScheduler.FromCurrentSynchronizationContext()); t.Start(); Thread.Sleep(Timeout.Infinite); }
相比较原来的Wait而言,不会卡死子线程,而且又可以多任务运行。
欲想知道更多关于线程操作的东西,可以参考:
MSDN,并行处理系列篇:http://msdn.microsoft.com/zh-cn/library/vstudio/3e8s7xdd(v=vs.110).aspx
标签:
版权申明:本站文章部分自网络,如有侵权,请联系:west999com@outlook.com
特别注意:本站所有转载文章言论不代表本站观点,本站所提供的摄影照片,插画,设计作品,如需使用,请与原作者联系,版权归原作者所有
- Delphi Format、FormatFloat与FormatDateTime的用法 2020-05-22
- delphi TStringList 用法详解 2019-10-12
- .NET中的计时器控件Timer 2018-06-21
- 数据库语法01 2018-06-21
- 关于路径的一些总结 2018-06-21
IDC资讯: 主机资讯 注册资讯 托管资讯 vps资讯 网站建设
网站运营: 建站经验 策划盈利 搜索优化 网站推广 免费资源
网络编程: Asp.Net编程 Asp编程 Php编程 Xml编程 Access Mssql Mysql 其它
服务器技术: Web服务器 Ftp服务器 Mail服务器 Dns服务器 安全防护
软件技巧: 其它软件 Word Excel Powerpoint Ghost Vista QQ空间 QQ FlashGet 迅雷
网页制作: FrontPages Dreamweaver Javascript css photoshop fireworks Flash