Task类学习教程—组合任务.ContinueWith

一、简介

通过任务,可以指定在任务完成之后,应开始运行之后另一个特定任务。ContinueWith是Task根据其自身状况,决定后续应该作何操作。也就是说,在运行完task后,会执行task.continuewith(XX)中的XX语句,但是是否执行、如何执行等需要看task的运行情况。例如:一个使用前一个任务的结果的新任务,如果前一个任务失败了,这个任务就应执行一些清理工作。任务处理程序都不带参数或者带一个对象参数,而任务的连续处理方法都有一个Task类型的参数。

二、案例

案例一:

代码:

  1. static int TaskMethod(string name, int seconds)
  2. {
  3. Console.WriteLine("Frist Task Method : Task {0} is running on a thread id: {1}. Is thread pool thread: {2}",
  4. name, Thread.CurrentThread.ManagedThreadId, Thread.CurrentThread.IsThreadPoolThread);
  5. Thread.Sleep(TimeSpan.FromSeconds(seconds));
  6. return 60 * seconds;
  7. }
  8. static void Main(string[] args)
  9. {
  10.  
  11. var FirstTask = new Task<int>(() => TaskMethod("Frist Task", 3));
  12. FirstTask.ContinueWith(t => Console.WriteLine("Frist Task Result: {0}. Thread id: {1}, Is in Thred Pool: {2}",
  13. t.Result, Thread.CurrentThread.ManagedThreadId, Thread.CurrentThread.IsThreadPoolThread),
  14. TaskContinuationOptions.OnlyOnRanToCompletion);//線程池線程
  15. FirstTask.Start();
  16.  
  17. Console.ReadKey();
  18. }

结果:

Start()和ContinueWith()的先后顺序没有关系,ContinueWith()会等待直到firstTask运行状态达到 IsCompleted,因为TaskContinuationOptions中的OnlyOnRanToCompletion.必须指出的是,ContinueWith()中的参数是需要以Task为参数的,也就是firstTask作为参数被传入,而且ContinueWith()运行在线程池中的线程中。我觉得比较重要的一点是:把ContinueWith()中的语句当做一块新的语句块,他们独立于主线程。无论如何,他们都要被判断,如果状态(status)不满足,那么他们不执行;当指定了多个状态,则使用合理的对应状态。

案例二:

代码:

  1. class Program
  2. {
  3. static int TaskMethod(string name, int seconds)
  4. {
  5. Console.WriteLine("Task Method : Task {0} is running on a thread id: {1}. Is thread pool thread: {2}",
  6. name, Thread.CurrentThread.ManagedThreadId, Thread.CurrentThread.IsThreadPoolThread);
  7. Thread.Sleep(TimeSpan.FromSeconds(seconds));
  8. return 60 * seconds;
  9. }
  10. static void Main(string[] args)
  11. {
  12. Console.WriteLine("Main Thread id {0}, Is in Thred Pool: {1}",
  13. Thread.CurrentThread.ManagedThreadId, Thread.CurrentThread.IsThreadPoolThread);
  14.  
  15. var firstTask = new Task<int>(() => TaskMethod("frist task", 3));
  16. var secondTask = new Task<int>(() => TaskMethod("second task", 2));
  17.  
  18. firstTask.ContinueWith(t => Console.WriteLine("Result:Frist Thread Result: {0}. Thread id: {1}, Is in Thred Pool: {2}",
  19. t.Result, Thread.CurrentThread.ManagedThreadId, Thread.CurrentThread.IsThreadPoolThread),
  20. TaskContinuationOptions.OnlyOnRanToCompletion);
  21.  
  22. firstTask.Start();
  23. secondTask.Start();
  24.  
  25. Thread.Sleep(TimeSpan.FromSeconds(4)); //给予足够时间,让firstTask、secondTask及其后续操作执行完毕。
  26.  
  27. Task continuation = secondTask.ContinueWith(t => Console.WriteLine("Result:Second Thread Result: {0}. Thread id: {1}, Is in Thred Pool: {2}",
  28. t.Result, Thread.CurrentThread.ManagedThreadId, Thread.CurrentThread.IsThreadPoolThread),
  29. TaskContinuationOptions.OnlyOnRanToCompletion | TaskContinuationOptions.ExecuteSynchronously);
  30. Console.ReadLine();
  31. Console.ReadKey();
  32. }
  33. }

结果:

这里主线程休眠了足足4秒钟,足以让firstTask和secondTask两个任务完成运行,而后,由于secondTask的后续除了接受OnlyOnRanToCompletion外,还接受ExecuteSynchronously。因此,后续运行中,由于主线程还没有结束,因此 ExecuteSynchronously得到认可,故secondTask的后续是在主线程上运行。

案例三:

代码:

  1. class Program
  2. {
  3. static int TaskMethod(string name, int seconds)
  4. {
  5. Console.WriteLine("Task Method : Task {0} is running on a thread id: {1}. Is thread pool thread: {2}",
  6. name, Thread.CurrentThread.ManagedThreadId, Thread.CurrentThread.IsThreadPoolThread);
  7. Thread.Sleep(TimeSpan.FromSeconds(seconds));
  8. return 60 * seconds;
  9. }
  10. static void Main(string[] args)
  11. {
  12. Console.WriteLine("Main Thread id {0}, Is in Thred Pool: {1}",
  13. Thread.CurrentThread.ManagedThreadId, Thread.CurrentThread.IsThreadPoolThread);
  14.  
  15. var firstTask = new Task<int>(() => TaskMethod("frist task", 3));
  16. var secondTask = new Task<int>(() => TaskMethod("second task", 2));
  17.  
  18. firstTask.ContinueWith(t => Console.WriteLine("Result:Frist Thread Result: {0}. Thread id: {1}, Is in Thred Pool: {2}",
  19. t.Result, Thread.CurrentThread.ManagedThreadId, Thread.CurrentThread.IsThreadPoolThread),
  20. TaskContinuationOptions.OnlyOnRanToCompletion);
  21.  
  22. firstTask.Start();
  23. secondTask.Start();
  24.  
  25. //Thread.Sleep(TimeSpan.FromSeconds(4)); //给予足够时间,让firstTask、secondTask及其后续操作执行完毕。
  26.  
  27. Task continuation = secondTask.ContinueWith(t => Console.WriteLine("Result:Second Thread Result: {0}. Thread id: {1}, Is in Thred Pool: {2}",
  28. t.Result, Thread.CurrentThread.ManagedThreadId, Thread.CurrentThread.IsThreadPoolThread),
  29. TaskContinuationOptions.OnlyOnRanToCompletion | TaskContinuationOptions.ExecuteSynchronously);
  30. Console.ReadLine();
  31. Console.ReadKey();
  32. }
  33. }

结果:

然而,如果把4秒钟的休眠注释掉,那么由于主线程很早就结束了,因此secondTask只能接受到OnlyOnRanToCompletion,因此还是运行在线程池中。

Task类学习教程—组合任务ContinueWith的更多相关文章

  1. ArcGIS API for JavaScript 4.2学习笔记[31] (补充学习)Task类

    Task这个东西很有用,是AJS中用于解决各种乱七八糟任务的一个类.它有很多子类,有用于空间分析的,有用于空间查询的,等等. 这篇作为补充学习的第一篇,也是进阶学习的第一篇,我就改个写法. 我将使用思 ...

  2. Protocol Buffer学习教程之编译器与类文件(三)

    Protocol Buffer学习教程之编译器与类文件(三) 1. 概述 在前面两篇中,介绍了Protobuf的基本概念.应用场景.与protobuf的语法等.在此篇中将介绍如何自己编译protobu ...

  3. Deep Learning 10_深度学习UFLDL教程:Convolution and Pooling_exercise(斯坦福大学深度学习教程)

    前言 理论知识:UFLDL教程和http://www.cnblogs.com/tornadomeet/archive/2013/04/09/3009830.html 实验环境:win7, matlab ...

  4. MySQL中的联合索引学习教程

    MySQL中的联合索引学习教程 这篇文章主要介绍了MySQL中的联合索引学习教程,其中谈到了联合索引对排序的优化等知识点,需要的朋友可以参考下   联合索引又叫复合索引.对于复合索引:Mysql从左到 ...

  5. 基于ASP.NET MVC的ABP框架入门学习教程

    为什么使用ABP 我们近几年陆续开发了一些Web应用和桌面应用,需求或简单或复杂,实现或优雅或丑陋.一个基本的事实是:我们只是积累了一些经验或提高了对,NET的熟悉程度. 随着软件开发经验的不断增加, ...

  6. Deep Learning 19_深度学习UFLDL教程:Convolutional Neural Network_Exercise(斯坦福大学深度学习教程)

    理论知识:Optimization: Stochastic Gradient Descent和Convolutional Neural Network CNN卷积神经网络推导和实现.Deep lear ...

  7. MyBatis入门学习教程-使用MyBatis对表执行CRUD操作

    上一篇MyBatis学习总结(一)--MyBatis快速入门中我们讲了如何使用Mybatis查询users表中的数据,算是对MyBatis有一个初步的入门了,今天讲解一下如何使用MyBatis对use ...

  8. 子类重载父类的方法“parent::方法名”转于 恩聪PHP学习教程

    在PHP中不能定义重名的函数,也包括不能再同一个类中定义重名的方法,所以也就没有方法重载.单在子类中可以定义和父类重名的方法,因为父类的方法已经在子类中存在,这样在子类中就可以把从父类中继承过来的方法 ...

  9. Deep Learning 8_深度学习UFLDL教程:Stacked Autocoders and Implement deep networks for digit classification_Exercise(斯坦福大学深度学习教程)

    前言 1.理论知识:UFLDL教程.Deep learning:十六(deep networks) 2.实验环境:win7, matlab2015b,16G内存,2T硬盘 3.实验内容:Exercis ...

随机推荐

  1. 分页系列之一:SQL Server 分页存储过程

    以下为最基本的代码结构,SQL Server 2012 开始支持 CREATE PROCEDURE procXXX @Page int, --当前页码,从1开始 @PageSize int --每页记 ...

  2. aws EKS EFS storageclass PV PVC Pod

    storageclass [root@localhost specs]# cat storageclass.yaml kind: StorageClass apiVersion: storage.k8 ...

  3. Ionic5沉浸式状态栏 适配全面屏

    1. 在platforms/android/app/src/main目录中找到AndroidManifest.xml文件,修改文件中manifest → application → activity标 ...

  4. Google字体API使用简单示例

    一.前面的话 Google总会做些造福大众的事情,例如提供了web在线字体的API,这玩意其实去年就有了,但是字体种类手指头+脚趾头就可以数出来.but 最近,貌似Google对字体API进行了升级, ...

  5. 【Set】Set集合求并集,交集,差集

    /** * @author: Sam.yang * @date: 2020/11/16 11:14 * @desc: Set集合操作工具类 */ public class SetOptUtils { ...

  6. Windows PE导出表编程4(重构导出表实现私有函数导出)

    本次是尝试调用DLL里面的私有函数. 一: 之前先探索一下,首先可以考虑用偏移量来调用,就是如果知道了某个私有函数和某个导出的公共函数的相对便宜的话,直接加载dll获取公共函数地址,然后自己手动去偏移 ...

  7. [转载] 关于Win7 x64下过TP保护的一些思路,内核层过保护,驱动过保护

    首先特别感谢梦老大,本人一直没搞懂异常处理机制,看了他的教程之后终于明白了.在他的教程里我学到了不少东西.第一次在论坛发帖,就说说Win7 x64位下怎么过TP保护.如果有讲错的地方,还望指出.说不定 ...

  8. MySQL三种报错注入方式下的insert,update,delete命令注入示例

    select 查询数据(大部分) 在网站应用中进行数据显示查询操作 insert 插入数据 在网站应用中进行用户注册添加等操作 delete 删除数据 后台管理里面删除文章删除用户等操作 update ...

  9. CCNA 第一章 网络互联

    1: 网络互联基础 互联网络定义:使用路由器将多个网络连接起来,并配置IP或者IPV6协议的逻辑网络编址方案,便组成了互联网络. 导致LAN(局域网)拥塞的常见原因: (1):广播域或者冲突域中的主机 ...

  10. Securecrt 在win7下 字体太少问题

    用WIN7,觉得securecrt里面可用的字体太少了.很多都没有,比如lucida console,经过一番查找,终于找到解决问题的方法了. 原因就是win7里面的很多字体都被设置为隐藏了,所以se ...