第五节:Task构造函数之TaskCreationOptions枚举处理父子线程之间的关系。
一. 整体说明
揭秘:
通过F12查看Task类的源码(详见下面的截图),发现Task类的构造函数有有一个参数为:TaskCreationOptions类型,本章节可以算作是一个扩展章节,主要就来研究TaskCreationOptions类的作用。
该类主要用来处理父子线程之间的关系,重要的几个参数如下:
①.AttachedToParent:指定将任务附加到任务层次结构中的某个父级,父任务必须等待所有子任务执行完毕才能执行
(下面的例子task线程必须等task1和task2线程执行完毕才能执行)
②. DenyChildAttach: 不允许子任务附加到父任务上
(下面例子task不再等待task1和task2,和00的默认效果相同)
③. HideScheduler: 子任务不使用父类Task的Scheduler,而是使用默认的 (不进行测试)
④. LongRunning:当已知是长时间运行的任务,可以使用该选项 (不进行测试)
⑤. PreferFairness:类似于队列的感觉,尽可能公平的方式安排任务 (不进行测试)
源码如下:
// 摘要:
// 指定可控制任务的创建和执行的可选行为的标志。
[Serializable]
[Flags]
public enum TaskCreationOptions
{
// 摘要:
// 指定应使用默认行为。
None = ,
//
// 摘要:
// 提示 System.Threading.Tasks.TaskScheduler 以一种尽可能公平的方式安排任务,这意味着较早安排的任务将更可能较早运行,而较晚安排运行的任务将更可能较晚运行。
PreferFairness = ,
//
// 摘要:
// 指定某个任务将是运行时间长、粗粒度的操作。 它会向 System.Threading.Tasks.TaskScheduler 提示,过度订阅可能是合理的。
LongRunning = ,
//
// 摘要:
// 指定将任务附加到任务层次结构中的某个父级。
AttachedToParent = ,
//
// 摘要:
// 如果尝试附有子任务到创建的任务,指定 System.InvalidOperationException 将被引发。
DenyChildAttach = ,
//
// 摘要:
// 防止环境计划程序被视为已创建任务的当前计划程序。 这意味着像 StartNew 或 ContinueWith 创建任务的执行操作将被视为 System.Threading.Tasks.TaskScheduler.Default
// 当前计划程序。
HideScheduler = ,
}
二. 实际测试
这里我们主要通过代码来比较默认情况下、AttachedToParent、DenyChildAttach之间的效果, task线程内部有task1和task2线程,并且在task内部开启。
1. 默认情况
         {
             Stopwatch watch = new Stopwatch();
             watch.Start();
             Console.WriteLine("----------------- Task多线程测试  --------------------------");
             Console.WriteLine("----------------- button1_Click 开始 主线程id为:{0}  --------------------------", Thread.CurrentThread.ManagedThreadId);
             #region 00-默认
             {
                 Task task = new Task(() =>
                 {
                     Task task1 = new Task(() =>
                     {
                         Thread.Sleep();
                         Console.WriteLine("我是task1线程");
                     });
                     Task task2 = new Task(() =>
                     {
                         Thread.Sleep();
                         Console.WriteLine("我是task2线程");
                     });
                     task1.Start();
                     task2.Start();
                 });
                 task.Start();
                 task.Wait();   //单个线程的等待
                 Console.WriteLine("------------------我是主线程--------------------");
             }
             #endregion
             watch.Stop();
             Console.WriteLine("----------------- button1_Click 结束 主线程id为:{0}  总耗时:{1}--------------------------", Thread.CurrentThread.ManagedThreadId, watch.ElapsedMilliseconds);
         }
多次执行上述代码看效果:发现task线程执行完后,task1和task2才无序的执行。

2. AttachedToParent
作用:指定将任务附加到任务层次结构中的某个父级,父任务必须等待所有子任务执行完毕才能执行
          {
                 Task task = new Task(() =>
                 {
                     Task task1 = new Task(() =>
                     {
                         Thread.Sleep();
                         Console.WriteLine("我是task1线程");
                     }, TaskCreationOptions.AttachedToParent);
                     Task task2 = new Task(() =>
                     {
                         Thread.Sleep();
                         Console.WriteLine("我是task2线程");
                     }, TaskCreationOptions.AttachedToParent);
                     task1.Start();
                     task2.Start();
                 });
                 task.Start();
                 task.Wait();   //单个线程的等待
                 Console.WriteLine("------------------我是主线程--------------------");
             }
多次执行上述代码看效果:发现task线程必须等task1和task2执行完毕后才能执行(印证了AttachedToParent的作用),task1和task2无先后顺序。

3. DenyChildAttach
作用:不允许子任务附加到父任务上。
  {
                 Task task = new Task(() =>
                 {
                     Task task1 = new Task(() =>
                     {
                         Thread.Sleep();
                         Console.WriteLine("我是task1线程");
                     }, TaskCreationOptions.AttachedToParent);
                     Task task2 = new Task(() =>
                     {
                         Thread.Sleep();
                         Console.WriteLine("我是task2线程");
                     }, TaskCreationOptions.AttachedToParent);
                     task1.Start();
                     task2.Start();
                 }, TaskCreationOptions.DenyChildAttach);
                 task.Start();
                 task.Wait();   //单个线程的等待
                 Console.WriteLine("------------------我是主线程--------------------");
             }
多次执行上述代码看效果:发现task线程执行完后,task1和task2才无序的执行。(和上述的默认情况是一致的)
 

第五节:Task构造函数之TaskCreationOptions枚举处理父子线程之间的关系。的更多相关文章
- 并发编程概述  委托(delegate)  事件(event)  .net core 2.0 event bus 一个简单的基于内存事件总线实现  .net core 基于NPOI 的excel导出类,支持自定义导出哪些字段  基于Ace Admin 的菜单栏实现  第五节:SignalR大杂烩(与MVC融合、全局的几个配置、跨域的应用、C/S程序充当Client和Server)
		并发编程概述 前言 说实话,在我软件开发的头两年几乎不考虑并发编程,请求与响应把业务逻辑尽快完成一个星期的任务能两天完成绝不拖三天(剩下时间各种浪),根本不会考虑性能问题(能接受范围内).但随着工 ... 
- 第九节: 利用RemoteScheduler实现Sheduler的远程控制  第八节: Quartz.Net五大构件之SimpleThreadPool及其四种配置方案  第六节: 六类Calander处理六种不同的时间场景  第五节: Quartz.Net五大构件之Trigger的四大触发类  第三节: Quartz.Net五大构件之Scheduler(创建、封装、基本方法等)和Job(创建、关联
		第九节: 利用RemoteScheduler实现Sheduler的远程控制 一. RemoteScheduler远程控制 1. 背景: 在A服务器上部署了一个Scheduler,我们想在B服务器上 ... 
- Ext JS学习第十六天 事件机制event(一)  DotNet进阶系列(持续更新)  第一节:.Net版基于WebSocket的聊天室样例  第十五节:深入理解async和await的作用及各种适用场景和用法  第十五节:深入理解async和await的作用及各种适用场景和用法  前端自动化准备和详细配置(NVM、NPM/CNPM、NodeJs、NRM、WebPack、Gulp/Grunt、G
		code&monkey Ext JS学习第十六天 事件机制event(一) 此文用来记录学习笔记: 休息了好几天,从今天开始继续保持更新,鞭策自己学习 今天我们来说一说什么是事件,对于事件 ... 
- 3 Task中的一些枚举 创建时候的、continue时候的
		创建时常用的枚举: None.PreferFairness.LongRunning.AttacthedToParent.DenyChildAttach.HideScheduler AttacthedT ... 
- 【C# task】TaskContinuationOptions 位枚举
		TaskContinuationOptions 根据 TaskContinuationOptions 的不同,出现了三个分支 LongRunning:独立线程,和线程池无关 包含 PreferFair ... 
- android内部培训视频_第五节(1)_OA实战之登录界面
		第五节(1):OA实战之登录界面 一.登录界面布局 1.背景图片 2.文本框 3.checkbox 4.按钮 暂未实现点击切换图片效果 <RelativeLayout xmlns:androi ... 
- 基于Extjs的web表单设计器 第五节——数据库设计
		这里列出表单设计器系列的内容,6.7.8节的内容应该在春节后才有时间出了.因为这周末就请假回老家了,准备我的结婚大事.在此提前祝大家春节快乐! 基于Extjs的web表单设计器 基于Extjs的web ... 
- [改善Java代码]使用构造函数协助描述枚举项
		一.分析 一般来说,我们经常使用的枚举项只有一个属性,即排序号,其默认值是从0.1.2... ....但是除了排序号外,枚举还有一个(或多个)属性:枚举描述,它的含义是通过枚举的构造函数,声明每个枚举 ... 
- JAVA GC之标记  第五节
		JAVA GC之标记 第五节 OK,我们继续昨天最后留下的问题,什么是标记?怎么标记? 第一个问题相信大家都知道,标记就是对一些已死的对象打上记号,方便垃圾收集器的清理. 至于怎么标记,一般有两种方 ... 
随机推荐
- Git常用命令集锦
			本篇Git命令博客主要是一些Git常用命令,适合于有一定Git或linux基础的小伙伴进行参考 1.新建文件夹 mkdir 文件夹名 2.查看目录机构: pwd 3.将文件添加至Git管理范围:git ... 
- Eclipse编程中免除alt+斜杠,设置自动提示
			用eclipse进行编程时,设置自动提示 .abcdefghijklmnopqrstuvwxyz@ 
- (九)Delete an Index
			Now let’s delete the index that we just created and then list all the indexes again: 现在让我们删除刚刚创建的索引, ... 
- spring boot整合mybatis基于注解开发以及动态sql的使用
			让我们回忆一下上篇博客中mybatis是怎样发挥它的作用的,主要是三类文件,第一mapper接口,第二xml文件,第三全局配置文件(application.properties),而今天我们就是来简化 ... 
- TestNG安装及使用
			安装:https://www.cnblogs.com/xusweeter/p/6559196.html使用:https://www.cnblogs.com/liwu/p/5113936.html 作用 ... 
- L2-4 部落 (25 分)
			在一个社区里,每个人都有自己的小圈子,还可能同时属于很多不同的朋友圈.我们认为朋友的朋友都算在一个部落里,于是要请你统计一下,在一个给定社区中,到底有多少个互不相交的部落?并且检查任意两个人是否属于同 ... 
- SpringBoot系列十:SpringBoot整合Redis
			声明:本文来源于MLDN培训视频的课堂笔记,写在这里只是为了方便查阅. 1.概念:SpringBoot 整合 Redis 2.背景 Redis 的数据库的整合在 java 里面提供的官方工具包:jed ... 
- 终于有人把“TCC分布式事务”实现原理讲明白了!
			之前网上看到很多写分布式事务的文章,不过大多都是将分布式事务各种技术方案简单介绍一下.很多朋友看了还是不知道分布式事务到底怎么回事,在项目里到底如何使用. 所以这篇文章,就用大白话+手工绘图,并结合一 ... 
- 看完python这段爬虫代码,java流泪了c#沉默了
			哈哈,其实很简单,寥寥几行代码网页爬一部小说,不卖关子,立刻开始. 首先安装所需的包,requests,BeautifulSoup4 控制台执行 pip install requests pip in ... 
- java异常处理规范
			异常处理的优势[存在意义]:异常检测者有检测出异常的能力,但不知道在出现该异常的情况下应该怎么处理.故库方法一般会抛出异常给调用者来处理.所以总结而言,异常处理的优势就是,将处理错误(调用者处理)从检 ... 
