一. 整体说明

揭秘:

  通过F12查看Task类的源码(详见下面的截图),发现Task类的构造函数有有一个参数为:TaskCreationOptions类型,本章节可以算作是一个扩展章节,主要就来研究TaskCreationOptions类的作用。

  该类主要用来处理父子线程之间的关系,重要的几个参数如下: 

  ①.AttachedToParent:指定将任务附加到任务层次结构中的某个父级,父任务必须等待所有子任务执行完毕才能执行

    (下面的例子task线程必须等task1和task2线程执行完毕才能执行)

  ②. DenyChildAttach: 不允许子任务附加到父任务上

    (下面例子task不再等待task1和task2,和00的默认效果相同)

  ③. HideScheduler: 子任务不使用父类Task的Scheduler,而是使用默认的 (不进行测试)

  ④. LongRunning:当已知是长时间运行的任务,可以使用该选项 (不进行测试)

  ⑤. PreferFairness:类似于队列的感觉,尽可能公平的方式安排任务 (不进行测试)

源码如下:

 1  // 摘要: 2     //     指定可控制任务的创建和执行的可选行为的标志。3     [Serializable]4     [Flags]5     public enum TaskCreationOptions6     {7         // 摘要: 8         //     指定应使用默认行为。9         None = 0,
10         //
11         // 摘要:
12         //     提示 System.Threading.Tasks.TaskScheduler 以一种尽可能公平的方式安排任务,这意味着较早安排的任务将更可能较早运行,而较晚安排运行的任务将更可能较晚运行。
13         PreferFairness = 1,
14         //
15         // 摘要:
16         //     指定某个任务将是运行时间长、粗粒度的操作。 它会向 System.Threading.Tasks.TaskScheduler 提示,过度订阅可能是合理的。
17         LongRunning = 2,
18         //
19         // 摘要:
20         //     指定将任务附加到任务层次结构中的某个父级。
21         AttachedToParent = 4,
22         //
23         // 摘要:
24         //     如果尝试附有子任务到创建的任务,指定 System.InvalidOperationException 将被引发。
25         DenyChildAttach = 8,
26         //
27         // 摘要:
28         //     防止环境计划程序被视为已创建任务的当前计划程序。 这意味着像 StartNew 或 ContinueWith 创建任务的执行操作将被视为 System.Threading.Tasks.TaskScheduler.Default
29         //     当前计划程序。
30         HideScheduler = 16,
31     }

二. 实际测试

  这里我们主要通过代码来比较默认情况下、AttachedToParent、DenyChildAttach之间的效果, task线程内部有task1和task2线程,并且在task内部开启。

1. 默认情况

 1         {2             Stopwatch watch = new Stopwatch();3             watch.Start();4             Console.WriteLine("----------------- Task多线程测试  --------------------------");5             Console.WriteLine("----------------- button1_Click 开始 主线程id为:{0}  --------------------------", Thread.CurrentThread.ManagedThreadId);6 7             #region 00-默认8             {9                 Task task = new Task(() =>
10                 {
11                     Task task1 = new Task(() =>
12                     {
13                         Thread.Sleep(1000);
14                         Console.WriteLine("我是task1线程");
15                     });
16                     Task task2 = new Task(() =>
17                     {
18                         Thread.Sleep(1000);
19                         Console.WriteLine("我是task2线程");
20                     });
21
22                     task1.Start();
23                     task2.Start();
24                 });
25
26                 task.Start();
27                 task.Wait();   //单个线程的等待
28                 Console.WriteLine("------------------我是主线程--------------------");
29             }
30             #endregion
31
32             watch.Stop();
33             Console.WriteLine("----------------- button1_Click 结束 主线程id为:{0}  总耗时:{1}--------------------------", Thread.CurrentThread.ManagedThreadId, watch.ElapsedMilliseconds);
34         }

  多次执行上述代码看效果:发现task线程执行完后,task1和task2才无序的执行。

2. AttachedToParent

  作用:指定将任务附加到任务层次结构中的某个父级,父任务必须等待所有子任务执行完毕才能执行

 1          {2                 Task task = new Task(() =>3                 {4                     Task task1 = new Task(() =>5                     {6                         Thread.Sleep(3000);7                         Console.WriteLine("我是task1线程");8                     }, TaskCreationOptions.AttachedToParent);9                     Task task2 = new Task(() =>
10                     {
11                         Thread.Sleep(3000);
12                         Console.WriteLine("我是task2线程");
13                     }, TaskCreationOptions.AttachedToParent);
14
15                     task1.Start();
16                     task2.Start();
17                 });
18
19                 task.Start();
20                 task.Wait();   //单个线程的等待
21                 Console.WriteLine("------------------我是主线程--------------------");
22             }

  多次执行上述代码看效果:发现task线程必须等task1和task2执行完毕后才能执行(印证了AttachedToParent的作用),task1和task2无先后顺序。

3. DenyChildAttach

  作用:不允许子任务附加到父任务上。

 1  {2                 Task task = new Task(() =>3                 {4                     Task task1 = new Task(() =>5                     {6                         Thread.Sleep(3000);7                         Console.WriteLine("我是task1线程");8                     }, TaskCreationOptions.AttachedToParent);9                     Task task2 = new Task(() =>
10                     {
11                         Thread.Sleep(3000);
12                         Console.WriteLine("我是task2线程");
13                     }, TaskCreationOptions.AttachedToParent);
14
15                     task1.Start();
16                     task2.Start();
17                 }, TaskCreationOptions.DenyChildAttach);
18
19                 task.Start();
20                 task.Wait();   //单个线程的等待
21                 Console.WriteLine("------------------我是主线程--------------------");
22             }

多次执行上述代码看效果:发现task线程执行完后,task1和task2才无序的执行。(和上述的默认情况是一致的)

 

第五节:Task构造函数之TaskCreationOptions枚举处理父子线程之间的关系。相关推荐

  1. 面向过程和面向对象的编程思想 复习原型 构造函数和实例对象和原型对象之间的关系

    体会面向过程和面向对象的编程思想 <!DOCTYPE html> <html lang="en"> <head><meta charset ...

  2. Kotlin学习笔记 第二章 类与对象 第五节 可见性 第六节 扩展

    参考链接 Kotlin官方文档 https://kotlinlang.org/docs/home.html 中文网站 https://www.kotlincn.net/docs/reference/p ...

  3. 第七章:小朱笔记hadoop之源码分析-hdfs分析 第五节:Datanode 分析

    第七章:小朱笔记hadoop之源码分析-hdfs分析 第五节:Datanode 分析 5.1 Datanode 启动过程分析 5.2 Datanode 心跳分析 5.3 Datanode 注册分析 5 ...

  4. 第五节 RabbitMQ在C#端的应用-消息收发

    原文:第五节 RabbitMQ在C#端的应用-消息收发 版权声明:未经本人同意,不得转载该文章,谢谢 https://blog.csdn.net/phocus1/article/details/873 ...

  5. 【java】兴唐课程第五节到第九节知识点总结

    第九节 1. 代码:void readBook(String- bookNames) 表示不确定参数的个数,此时变量为一个数组. 2.当方法中的参数名称(如stuname)和属性名称相同时. this ...

  6. Simulink仿真 第五节 复用器和分路器

    第五节 复用器和分路器 1.复用器(将多个输入信号合并为矢量) Mux 模块可将其输入合并为单个矢量输出.输入可以是标量或矢量信号.所有输入都必须具有相同的数据类型和数值类型.矢量输出信号元素采用输入 ...

  7. Python编程基础:第五十五节 map函数Map

    第五十五节 map函数Map 前言 实践 前言 map函数的作用是将指定函数作用于一个可迭代对象内部的每一个元素,其表达方式为map(function, iterable),第一个位置指定作用函数,第 ...

  8. Python编程基础:第四十五节 方法链Method Chaining

    第四十五节 方法链Method Chaining 前言 实践 前言 方法链是指一个对象一次调用其自身的多个方法,通常写作对象.方法1.方法2.由于这种调用方法看起来像一个链条,所以我们将其称作方法链. ...

  9. Python编程基础:第三十五节 文件删除Delete a File

    第三十五节 文件删除Delete a File 前言 实践 前言 我们这一节来介绍如何删除一个文件,这里需要用到函数os.remove(path)用于删除指定路径下的文件,os.rmdir(path) ...

最新文章

  1. CSS里常见的块级元素和行内元素
  2. JavaScript脚本放在哪里
  3. 【LeetCode从零单排】No.160 Intersection of Two Linked Lists
  4. 传百度最高决策层Estaff成员王路将离职,官方暂未回应...
  5. Spring AOP(四)之After增强处理
  6. 编写简单的触摸屏驱动程序——基于QEMU
  7. win10计算机安全策略设置,win10系统重置本地安全策略所有设置的操作方法
  8. FMCW激光雷达原理推导公式
  9. UE_GPU Driven Pipeline Mesh Shader(meshlet)
  10. 《java程序设计基础》 抽象类
  11. SQLI DUMB SERIES-6
  12. 全“芯”升级,浩辰CAD 2021赋能全国产化CAD应用
  13. 计算机论文的致谢部分写什么,毕业论文致谢部分怎么写
  14. 问题 C: 合唱队形
  15. 微信小程序获取unionID思路整理
  16. 10000+门店的蜜雪冰城,帮你找回软件赚钱的初心
  17. Linux下for语句
  18. 【毕业设计】【期末作业】新闻发布系统(php+mysql)
  19. c语言上机作业题及答案,C语言上机练习题及答案
  20. 异构数据库迁移的曲折之路

热门文章

  1. 常见三种字符编码的区别:ASCII、Unicode、UTF-8
  2. 【转载】linux进程及进程控制
  3. codeforces B. The Fibonacci Segment 解题报告
  4. Microsoft Visual Studio 打开代码出现乱码解决方案
  5. 310. Minimum Height Trees
  6. [剑指offer]面试题第[56-2]题[JAVA][数组中数字出现的次数][状态机][hashmap][位运算]
  7. 【模板】在build中配置resources来防止我们资源导出失败的问题
  8. dft计算傅里叶级数系数_一道国外的DFT性质的题目
  9. 801. 二进制中1的个数
  10. 计算机软考有学历限制吗,软考中级职称申请积分还需要学历吗?