第六节:深入研究Task实例方法ContinueWith的参数TaskContinuationOptions
一. 整体说明
揭秘:
该章节的性质和上一个章节类似,也是一个扩展的章节,主要来研究Task类下的实例方法ContinueWith中的参数TaskContinuationOptions。
通过F12查看TaskContinuationOptions的源码,知道主要有这么几个参数:
①. LazyCancellation:在延续取消的情况下,防止延续的完成直到完成先前的任务。
(下面的例子task2取消,原先的延续关系不复存在,task1和task3可以并行执行)
②. ExecuteSynchronously:希望执行前面那个task的thread也在执行本延续任务
(下面的例子执行task2的Thread和执行task1的Thread是同一个,所有二者的线程id相同)
③. NotOnRanToCompletion和OnlyOnRanToCompletion
NotOnRanToCompletion:延续任务必须在前面task非完成状态才能执行
OnlyOnRanToCompletion:延续任务必须在前面task完成状态才能执行
(下面例子:注释掉异常的这句代码task2不能执行,task3能执行;不注释,task2能执行,task3不能执行)
源码如下:
[Serializable]
[Flags]
public enum TaskContinuationOptions
{
// 摘要:
// Default = "Continue on any, no task options, run asynchronously" 指定应使用默认行为。
// 默认情况下,完成前面的任务之后将安排运行延续任务,而不考虑前面任务的最终 System.Threading.Tasks.TaskStatus。
None = ,
//
// 摘要:
// 提示 System.Threading.Tasks.TaskScheduler 以一种尽可能公平的方式安排任务,这意味着较早安排的任务将更可能较早运行,而较晚安排运行的任务将更可能较晚运行。
PreferFairness = ,
//
// 摘要:
// 指定某个任务将是运行时间长、粗粒度的操作。 它会向 System.Threading.Tasks.TaskScheduler 提示,过度订阅可能是合理的。
LongRunning = ,
//
// 摘要:
// 指定将任务附加到任务层次结构中的某个父级。
AttachedToParent = ,
//
// 摘要:
// 如果尝试附有子任务到创建的任务,指定 System.InvalidOperationException 将被引发。
DenyChildAttach = ,
//
// 摘要:
// 防止环境计划程序被视为已创建任务的当前计划程序。 这意味着像 StartNew 或 ContinueWith 创建任务的执行操作将被视为 System.Threading.Tasks.TaskScheduler.Default
// 当前计划程序。
HideScheduler = ,
//
// 摘要:
// 在延续取消的情况下,防止延续的完成直到完成先前的任务。
LazyCancellation = ,
//
// 摘要:
// 指定不应在延续任务前面的任务已完成运行的情况下安排延续任务。 此选项对多任务延续无效。
NotOnRanToCompletion = ,
//
// 摘要:
// 指定不应在延续任务前面的任务引发了未处理异常的情况下安排延续任务。 此选项对多任务延续无效。
NotOnFaulted = ,
//
// 摘要:
// 指定只应在延续任务前面的任务已取消的情况下才安排延续任务。 此选项对多任务延续无效。
OnlyOnCanceled = ,
//
// 摘要:
// 指定不应在延续任务前面的任务已取消的情况下安排延续任务。 此选项对多任务延续无效。
NotOnCanceled = ,
//
// 摘要:
// 指定只应在延续任务前面的任务引发了未处理异常的情况下才安排延续任务。 此选项对多任务延续无效。
OnlyOnFaulted = ,
//
// 摘要:
// 指定只应在延续任务前面的任务已完成运行的情况下才安排延续任务。 此选项对多任务延续无效。
OnlyOnRanToCompletion = ,
//
// 摘要:
// 指定应同步执行延续任务。 指定此选项后,延续任务将在导致前面的任务转换为其最终状态的相同线程上运行。 如果在创建延续任务时已经完成前面的任务,则延续任务将在创建此延续任务的线程上运行。
// 只应同步执行运行时间非常短的延续任务。
ExecuteSynchronously = ,
}
二. 实际测试
下面通过代码来说明默认情况下、LazyCancellation、ExecuteSynchronously、NotOnRanToCompletion和OnlyOnRanToCompletion的作用和效果。
1. 默认情况
默认情况下,task1执行完后→task2→task2执行完后→task3。
{
Task task1 = new Task(() =>
{
Thread.Sleep();
Console.WriteLine("task1 tid={0}, dt={1}", Thread.CurrentThread.ManagedThreadId, DateTime.Now);
}); var task2 = task1.ContinueWith(t =>
{
Console.WriteLine("task2 tid={0}, dt={1}", Thread.CurrentThread.ManagedThreadId, DateTime.Now);
}); var task3 = task2.ContinueWith(t =>
{
Console.WriteLine("task3 tid={0}, dt={1} {2}", Thread.CurrentThread.ManagedThreadId, DateTime.Now, task2.Status);
}); task1.Start(); }
运行结果: task1执行完后→ task2执行→task2执行完后→ task3执行。
2. LazyCancellation
作用:取消该线程,该线程的前一个线程和后一个线程并行执行。
{
CancellationTokenSource source = new CancellationTokenSource();
source.Cancel(); Task task1 = new Task(() =>
{
Thread.Sleep();
Console.WriteLine("task1 tid={0}, dt={1}", Thread.CurrentThread.ManagedThreadId, DateTime.Now);
}); var task2 = task1.ContinueWith(t =>
{
Console.WriteLine("task2 tid={0}, dt={1}", Thread.CurrentThread.ManagedThreadId, DateTime.Now);
}, source.Token, TaskContinuationOptions.LazyCancellation, TaskScheduler.Current); var task3 = task2.ContinueWith(t =>
{
Console.WriteLine("task3 tid={0}, dt={1} {2}", Thread.CurrentThread.ManagedThreadId, DateTime.Now, task2.Status);
}); task1.Start(); }
运行结果: task2线程已经被取消,task1线程和task2线程并行执行。
3. ExecuteSynchronously
作用:希望执行前面那个task的thread也在执行本延续任务。
{
Task task1 = new Task(() =>
{
Thread.Sleep();
Console.WriteLine("task1 tid={0}, dt={1}", Thread.CurrentThread.ManagedThreadId, DateTime.Now);
}); var task2 = task1.ContinueWith(t =>
{
Console.WriteLine("task2 tid={0}, dt={1}", Thread.CurrentThread.ManagedThreadId, DateTime.Now);
}, TaskContinuationOptions.ExecuteSynchronously); task1.Start();
}
结果:task1和task2线程的线程id相同。
4. NotOnRanToCompletion和OnlyOnRanToCompletion
NotOnRanToCompletion:延续任务必须在前面task非完成状态才能执行。
OnlyOnRanToCompletion:延续任务必须在前面task完成状态才能执行。
{
Task task1 = new Task(() =>
{
Thread.Sleep();
Console.WriteLine("task1 tid={0}, dt={1}", Thread.CurrentThread.ManagedThreadId, DateTime.Now);
//手动制造异常,表示不能执行完毕
//(注释掉这句话task2不能执行,task3能执行)
//不注释,task2能执行,task3不能执行
//throw new Exception("hello world");
}); var task2 = task1.ContinueWith(t =>
{
Console.WriteLine("task2 tid={0}, dt={1}", Thread.CurrentThread.ManagedThreadId, DateTime.Now);
}, TaskContinuationOptions.NotOnRanToCompletion); var task3 = task1.ContinueWith(t =>
{
Console.WriteLine("task3 tid={0}, dt={1}", Thread.CurrentThread.ManagedThreadId, DateTime.Now);
}, TaskContinuationOptions.OnlyOnRanToCompletion); task1.Start();
}
分析:task2和task3均为task的延续线程,当task1报错时候,task2执行,task3不能执行;当task1正常时候,task2不能执行,task3能执行。
task1报错时的运行结果:
task2正常时的运行结果:
第六节:深入研究Task实例方法ContinueWith的参数TaskContinuationOptions的更多相关文章
- VUE2.0实现购物车和地址选配功能学习第六节
第六节 地址列表过滤和展开所有的地址 html:<li v-for="(item,index) in filterAddress">js: new Vue({ el:' ...
- 第四百一十六节,Tensorflow简介与安装
第四百一十六节,Tensorflow简介与安装 TensorFlow是什么 Tensorflow是一个Google开发的第二代机器学习系统,克服了第一代系统DistBelief仅能开发神经网络算法.难 ...
- 第九节: 利用RemoteScheduler实现Sheduler的远程控制 第八节: Quartz.Net五大构件之SimpleThreadPool及其四种配置方案 第六节: 六类Calander处理六种不同的时间场景 第五节: Quartz.Net五大构件之Trigger的四大触发类 第三节: Quartz.Net五大构件之Scheduler(创建、封装、基本方法等)和Job(创建、关联
第九节: 利用RemoteScheduler实现Sheduler的远程控制 一. RemoteScheduler远程控制 1. 背景: 在A服务器上部署了一个Scheduler,我们想在B服务器上 ...
- CUDA:Supercomputing for the Masses (用于大量数据的超级计算)-第六节
原文链接 第六节:全局内存和CUDA RPOFILER Rob Farber 是西北太平洋国家实验室(Pacific Northwest National Laboratory)的高级科研人员.他在 ...
- 风炫安全web安全学习第三十六节课-15种上传漏洞讲解(一)
风炫安全web安全学习第三十六节课 15种上传漏洞讲解(一) 文件上传漏洞 0x01 漏洞描述和原理 文件上传漏洞可以说是日常渗透测试用得最多的一个漏洞,因为用它获得服务器权限最快最直接.但是想真正把 ...
- 基于Extjs的web表单设计器 第六节——界面框架设计
基于Extjs的web表单设计器 基于Extjs的web表单设计器 第一节 基于Extjs的web表单设计器 第二节——表单控件设计 基于Extjs的web表单设计器 第三节——控件拖放 基于Extj ...
- 第一百二十六节,JavaScript,XPath操作xml节点
第一百二十六节,JavaScript,XPath操作xml节点 学习要点: 1.IE中的XPath 2.W3C中的XPath 3.XPath跨浏览器兼容 XPath是一种节点查找手段,对比之前使用标准 ...
- delphi 线程教学第六节:TList与泛型
第六节: TList 与泛型 TList 是一个重要的容器,用途广泛,配合泛型,更是如虎添翼. 我们先来改进一下带泛型的 TList 基类,以便以后使用. 本例源码下载(delphi XE8版本) ...
- 第十六节、基于ORB的特征检测和特征匹配
之前我们已经介绍了SIFT算法,以及SURF算法,但是由于计算速度较慢的原因.人们提出了使用ORB来替代SIFT和SURF.与前两者相比,ORB有更快的速度.ORB在2011年才首次发布.在前面小节中 ...
随机推荐
- LeetCode算法题-To Lower Case(Java实现)
这是悦乐书的第301次更新,第320篇原创 01 看题和准备 今天介绍的是LeetCode算法题中Easy级别的第169题(顺位题号是709).实现具有字符串参数str的函数ToLowerCase() ...
- 【模块04-大数据技术入门】02节-HDFS核心知识
分布式存储 (1) 5PB甚至更大的数据集怎么存储 ? 所有数据分块,每个数据块冗余存储在多台机器上(冗余可提高数据块高可用性).另外一台机器上启动一个管理所有节点.以及存储在各节点上面数据块的服务. ...
- HBase源码实战:ImportTsv
/** * * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agr ...
- CodeChef Dynamic GCD
嘟嘟嘟vjudge 我今天解决了一个历史遗留问题! 题意:给一棵树,写一个东西,支持一下两种操作: 1.\(x\)到\(y\)的路径上的每一个点的权值加\(d\). 2.求\(x\)到\(y\)路径上 ...
- MyCP(课下作业,必做)
MyCP(课下作业,必做) 要求 编写MyCP.java 实现类似Linux下cp XXX1 XXX2 的功能,要求MyCP支持两个参数: java MyCP -tx XXX1.txt XXX2.bi ...
- ksar、sar及相关内核知识点解析
关键词:sar.sadc.ksar./proc/stat./proc/cpuinfo./proc/meminfo./proc/diskstats. 在之前有简单介绍过sar/ksar,最近在使用中感觉 ...
- 基于vue-simple-uploader封装文件分片上传、秒传及断点续传的全局上传插件
目录 1. 前言 2. 关于vue-simple-uploader 3. 基于vue-simple-uploader封装全局上传组件 4. 文件上传流程概览 5. 文件分片 6. MD5的计算过程 7 ...
- C#帮助类:将List转换成Datatable
public class ListToDatatable { public static DataTable ToDataTable <T> (List <T> items) ...
- HTML/CSS 速写神器 Emmet语法
Emmet 是高效.快速编写 HTML 和 CSS 代码的一种插件,如果还不了解,请戳Emmet — the essential toolkit for web-developers,再根据你使用的编 ...
- 在Asp.Net Core中使用DI的方式使用Hangfire构建后台执行脚本
最近项目中需要用到后台Job,原有在Windows中我们会使用命令行程序结合计划任务或者直接生成Windows Service,现在.Net Core跨平台了,虽然Linux下也有计划任务,但跟原有方 ...