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是一种起了线程之后就不管了的做法.但是实际应用过程,我们往往会有更多的需求,比如如果更简 ...
随机推荐
- .net Reflection(反射)- 二
反射 Reflection 中访问方法 新建一个ClassLibrary类库: public class Student { public string Name { get; set; } publ ...
- 【C#】 ref out
ref 通常我们向方法中传递的是值,方法获得的是这些值的一个拷贝,然后使用这些拷贝,当方法运行完毕后,这些拷贝将被丢弃,而原来的值不会受到影响. 这种情况是通常的,当然还有另外一种情况,我们向方法传递 ...
- 自用 Pycharm 主题配色分享(主题才是开发第一生产力)
写在前面的话 是的,我又回来了,上一篇[使用 Visual Studio Code(VSCode)搭建简单的 Python + Django 开发环境]才说真香,结果用两天就发现很多恶心的问题拦住了菜 ...
- JSP页面导出PDF格式文件
JSP页面导出PDF格式文件基本在前端页面可以全部完成 <script src="https://cdnjs.cloudflare.com/ajax/libs/html2canvas/ ...
- django 重写User表增加字段设置
models中: from django.contrib.auth.models import AbstractUser lass User(AbstractUser): mobile = model ...
- flink学习笔记-数据源(DataSource)
说明:本文为<Flink大数据项目实战>学习笔记,想通过视频系统学习Flink这个最火爆的大数据计算框架的同学,推荐学习课程: Flink大数据项目实战:http://t.cn/EJtKh ...
- luogu5212/bzoj2555 substring(后缀自动机+动态树)
对字符串构建一个后缀自动机. 每次查询的就是在转移边上得到节点的parent树中后缀节点数量. 由于强制在线,可以用动态树维护后缀自动机parent树的子树和. 注意一个玄学的优化:每次在执行连边操作 ...
- JDBC_设计架构_驱动类加载_建立Connection_效率测试
JDBC(Java DataBase Connection) 访问数据库流程:驱动管理器--连接数据库--sql语句--结果集 装载mysql驱动 Class.forName("com.jd ...
- URL编码以及GET和POST提交乱码解决方案
get方式时参数是作为url一部分传输的.而对于url是有规范的,汉字超出了规范的范围. post方式不需要加编码是错误的.post时也必须传送符合服务器规范的编码.如果错误,服务器收到的内容也不会正 ...
- 使用window.name 进行数据跨域传递
其中要点, Stpe1,浏览器在Iframe中加载一个异域的页面,这个页面返回 <script>window.name="任何数据"</script>,这时 ...