Task的一些用法总结
一、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 = ; i < ; i++)
{
// 调用Cancel方法,状态为true(表示已经取消了)
if (!ts.IsCancellationRequested)
{
if (i == )
{
// 该异常不会直接被主线程捕获
throw new Exception("数字是5,非法!");
}
}
else
{
Console.WriteLine("用户取消");
// 抛出异常,强制取消子线程
ct.ThrowIfCancellationRequested();
}
Console.WriteLine(i);
Thread.Sleep();
}
}, 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();
Console.WriteLine("任务一");
},
// 挂接到主线程,这样主线程会自动等待子线程完成后完成
TaskCreationOptions.AttachedToParent ); Task.Factory.StartNew(() =>
{
Thread.Sleep();
Console.WriteLine("任务二");
}, TaskCreationOptions.AttachedToParent); Task.Factory.StartNew(() =>
{
Thread.Sleep();
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
Task的一些用法总结的更多相关文章
- async,await,Task 的一些用法
async,await,Task 的一些用法 private void Form1_Load(object sender, EventArgs e) { Display(); } public asy ...
- c#4.0 Task.Factory.StartNew 用法
var t1 = Task.Factory.StartNew<string>(() => { return “1111111”; }); //t1.Wait(); t1.Contin ...
- C# Task.FromResult的用法
Task.FromResult用来创建一个带返回值的.已完成的Task. 场景一:以同步的方式实现一个异步接口方法比如有一个接口包含异步方法. interface IMyInterface { Tas ...
- Task WaitAll的用法
var tasklst = new List<Task>(); ; i < urls.Count; i++) { tasklst.Add(Task.Factory.StartNew& ...
- SSIS Execute SQL Task 用法
Execute Sql Task组件是一个非常有用的Control Flow Task,可以直接执行SQL语句,例如,可以执行数据更新命令(update,delete,insert),也可以执行sel ...
- C# Task 用法
C# Task 的用法 其实Task跟线程池ThreadPool的功能类似,不过写起来更为简单,直观.代码更简洁了,使用Task来进行操作.可以跟线程一样可以轻松的对执行的方法进行控制. 顺便提一下, ...
- C# Task 的用法
C# Task 的用法(转自:http://www.wxzzz.com/683.html#) 其实Task跟线程池ThreadPool的功能类似,不过写起来更为简单,直观.代码更简洁了,使用Task来 ...
- C#基础系列——多线程的常见用法详解
前言:前面几节分别介绍了下C#基础技术中的反射.特性.泛型.序列化.扩展方法.Linq to Xml等,这篇跟着来介绍下C#的另一基础技术的使用.最近项目有点紧张,所以准备也不是特别充分.此篇就主要从 ...
- 细说.NET中的多线程 (三 使用Task)
上一节我们介绍了线程池相关的概念以及用法.我们可以发现ThreadPool. QueueUserWorkItem是一种起了线程之后就不管了的做法.但是实际应用过程,我们往往会有更多的需求,比如如果更简 ...
随机推荐
- 课后练习Javascript
<script type="text/javascript"> alert (isNaN(prompt("输入个数字进来","只能输入数字 ...
- 不同数据库表结构的转化,PowerDesigner的使用教程
通过学习PowerDesigner工具,学习概念模型,物理模型,面向对象模型,业务模型,以及不同数据库表结构的转化. 通过案例给大家分享,sql server 2008r2 数据库和oracle数据库 ...
- p2p_server
以太坊系列之十九 对p2p模块server的理解 type transport interface { // The two handshakes. doEncHandshake(prv *ecdsa ...
- 后置处理器----JSON提取器
JSON提取器可以很方便的让你从JSON响应格式中提取数据. 1)Name:JSON提取器的名称. 2)Apply to:应用范围,有些采样器还嵌套子采样器,可以在此处设置JSON提取器是作用与主采样 ...
- 互斥锁与join
三 互斥锁与join 使用join可以将并发变成串行,互斥锁的原理也是将并发变成穿行,那我们直接使用join就可以了啊,为何还要互斥锁,说到这里我赶紧试了一下 #把文件db.txt的内容重置为:{&q ...
- B - N皇后问题
原文链接 一天课下,张老板研究起了国际象棋,渴望完美的他更改了棋盘的大小,在N*N的方格棋盘放置了N个皇后,希望它们不相互攻击(即任意2个皇后不允许处在同一排,同一列,也不允许处在与棋盘边框成45角的 ...
- servlet 核心技术
servlet 核心技术 servlet 生命周期 在 servlet 生命周期中,servlet 容器完成加载 servlet 类和实例化一个 servlet 实例,并通过3个方法来完成生命周期中的 ...
- 使用webpack开发ES6程序的正确姿势
1.cnpm install babel-loader babel-core babel-preset-es2015 -D 2.cnpm install babel-plugin-transform- ...
- error while loading shared libraies :libopencv_core_so.3.4:cannot open shared object
TX2 上安装自己编译的opencv,使用时出现: error while loading shared libraies :libopencv_core_so.3.4:cannot open sha ...
- 苹果内购和 Apple Pay
作者:CC老师_MissCC链接:http://www.jianshu.com/p/e3bc47e81785來源:简书 苹果内购 1.什么是内购? 如果你购买的商品,是在本app中使用和消耗的,就一定 ...