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

一、简介

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

二、案例

案例一:

代码:

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

结果:

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

案例二:

代码:

 class Program
{
static int TaskMethod(string name, int seconds)
{
Console.WriteLine("Task Method : Task {0} is running on a thread id: {1}. Is thread pool thread: {2}",
name, Thread.CurrentThread.ManagedThreadId, Thread.CurrentThread.IsThreadPoolThread);
Thread.Sleep(TimeSpan.FromSeconds(seconds));
return 60 * seconds;
}
static void Main(string[] args)
{
Console.WriteLine("Main Thread id {0}, Is in Thred Pool: {1}",
Thread.CurrentThread.ManagedThreadId, Thread.CurrentThread.IsThreadPoolThread); var firstTask = new Task<int>(() => TaskMethod("frist task", 3));
var secondTask = new Task<int>(() => TaskMethod("second task", 2)); firstTask.ContinueWith(t => Console.WriteLine("Result:Frist Thread Result: {0}. Thread id: {1}, Is in Thred Pool: {2}",
t.Result, Thread.CurrentThread.ManagedThreadId, Thread.CurrentThread.IsThreadPoolThread),
TaskContinuationOptions.OnlyOnRanToCompletion); firstTask.Start();
secondTask.Start(); Thread.Sleep(TimeSpan.FromSeconds(4)); //给予足够时间,让firstTask、secondTask及其后续操作执行完毕。 Task continuation = secondTask.ContinueWith(t => Console.WriteLine("Result:Second Thread Result: {0}. Thread id: {1}, Is in Thred Pool: {2}",
t.Result, Thread.CurrentThread.ManagedThreadId, Thread.CurrentThread.IsThreadPoolThread),
TaskContinuationOptions.OnlyOnRanToCompletion | TaskContinuationOptions.ExecuteSynchronously);
Console.ReadLine();
Console.ReadKey();
}
}

结果:

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

案例三:

代码:

   class Program
{
static int TaskMethod(string name, int seconds)
{
Console.WriteLine("Task Method : Task {0} is running on a thread id: {1}. Is thread pool thread: {2}",
name, Thread.CurrentThread.ManagedThreadId, Thread.CurrentThread.IsThreadPoolThread);
Thread.Sleep(TimeSpan.FromSeconds(seconds));
return 60 * seconds;
}
static void Main(string[] args)
{
Console.WriteLine("Main Thread id {0}, Is in Thred Pool: {1}",
Thread.CurrentThread.ManagedThreadId, Thread.CurrentThread.IsThreadPoolThread); var firstTask = new Task<int>(() => TaskMethod("frist task", 3));
var secondTask = new Task<int>(() => TaskMethod("second task", 2)); firstTask.ContinueWith(t => Console.WriteLine("Result:Frist Thread Result: {0}. Thread id: {1}, Is in Thred Pool: {2}",
t.Result, Thread.CurrentThread.ManagedThreadId, Thread.CurrentThread.IsThreadPoolThread),
TaskContinuationOptions.OnlyOnRanToCompletion); firstTask.Start();
secondTask.Start(); //Thread.Sleep(TimeSpan.FromSeconds(4)); //给予足够时间,让firstTask、secondTask及其后续操作执行完毕。 Task continuation = secondTask.ContinueWith(t => Console.WriteLine("Result:Second Thread Result: {0}. Thread id: {1}, Is in Thred Pool: {2}",
t.Result, Thread.CurrentThread.ManagedThreadId, Thread.CurrentThread.IsThreadPoolThread),
TaskContinuationOptions.OnlyOnRanToCompletion | TaskContinuationOptions.ExecuteSynchronously);
Console.ReadLine();
Console.ReadKey();
}
}

结果:

然而,如果把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. 754. Reach a Number

    You are standing at position 0 on an infinite number line. There is a goal at position target. On ea ...

  2. 从零开始使用git将本地项目上传到GitHub

    直接进入主题 1. 注册GitHub(官网:https://github.com/),打开官网,右上角点击sign up注册按钮,进入注册界面,根据提示填写信息注册. ​

  3. Java中的线程池用过吧?来说说你是怎么理解线程池吧?

    前言 Java中的线程池用过吧?来说说你是怎么使用线程池的?这句话在面试过程中遇到过好几次了.我甚至这次标题都想写成[Java八股文之线程池],但是有点太俗套了.虽然,线程池是一个已经被说烂的知识点了 ...

  4. 2.1.3- 体会css样式

    css初始 css样式规则 代码如下: <!DOCTYPE html> <html lang="en"> <head> <meta cha ...

  5. 5- MySQL数据库SELECT查询操作

    复习: 数据类型: 数值型:整数(int,tinyint,smallint,bigint,mediumint) 浮点型(float ,double,decimal) 字符型:char(固定长度) ,v ...

  6. linux删除文件空间不释放问题解决

    目录 场景描述 原因 解决方法 在线清空文件 场景描述 某天,收到Prometheus报警,生产中某台机器出现磁盘空间不足报警,该台服务器是mysql其中一台从库,远程登录到该服务后,排查磁盘空间的原 ...

  7. Dalvik模式下基于Android运行时类加载的函数dexFindClass脱壳

    本文博客地址:http://blog.csdn.net/qq1084283172/article/details/78003184 前段时间在看雪论坛发现了<发现一个安卓万能脱壳方法>这篇 ...

  8. Linux-鸟菜-6-文件搜索

    Linux-鸟菜-6-文件搜索 which(寻找[执行档]) alian ..............这个后面显示的是别名 没有找到history是因为which是根据PATH环境变阿玲去搜索执行文件 ...

  9. [CTF]栅栏密码

    [CTF]栅栏密码 ---------------------  作者:adversity`  来源:CSDN  原文:https://blog.csdn.net/qq_40836553/articl ...

  10. CTFHub-easy_search

    easy_search 玩了好些天,今天做道题找找状态,明天开始肝了 打开是一个登录框 用amdin/admin尝试了一下,提示登陆失败 这里肯定不会是暴力破解,我猜是sql注入,试了万能密码or 1 ...