Task.ContinueWith

这货,和 await 一样有“陷阱”。^^,因为写 ContinueWith 不能直观如人的“过程性”思维,写在 ContinueWith 括号里的部分不一定只在发起 ContinueWith 的任务完成后完成,比如这样:

 namespace TaskConsole
{
class Program
{
static void Main(string[] args)
{
while (true)
{
var enter = Console.ReadLine(); if (enter.ToLower() == "continue") { Entry(); }
else { break; }
}
} async static void DoWork(string workerName)
{
await Task.Delay();
Console.WriteLine("{0} is working @ Thread Id {1}", workerName, System.Threading.Thread.CurrentThread.ManagedThreadId);
} async static void DoClean(string cleaner)
{
await Task.Delay();
Console.WriteLine("{0} is cleaning @ Task Id {1}", cleaner, Task.CurrentId);
} async static Task Entry()
{
var task = Task.Factory.StartNew(() => DoWork("工作者1")).
ContinueWith(backer => DoClean("清理者1")).
ContinueWith(backer => DoClean("清理者2")).
ContinueWith(backer => DoClean("清理者3"));
}
}
}

运行一下试试?如果过程中没有 await Task.Delay 参与,看起来基本是按顺序的,但是这句一加上就立马露陷了,看

那如何让 ContinueWith 按我们的心思走呢?对了,还有其它参数可以用,让我们随便试试

 var task = Task.Factory.StartNew(() => DoWork("工作者1")).
ContinueWith(backer => DoClean("清理者1"), TaskContinuationOptions.NotOnRanToCompletion).
ContinueWith(backer => DoClean("清理者2"), TaskContinuationOptions.OnlyOnRanToCompletion).
ContinueWith(backer => DoClean("清理者3"), TaskContinuationOptions.OnlyOnRanToCompletion);

运行一下,咦,发生了什么?

为什么清理者都不工作了?问题出在参数 【TaskContinuationOptions.NotOnRanToCompletion】,它起了作用,它告诉第一个清理者“当工作者任务不是正常完成时你才能启动”,所以清理者1就没有机会启动,它没有机会启动,后面的清理者2、清理者3自然都没有办法启动。到这里只知道 ContinueWith 还有参数可以利用,但是没有达到我们的目的,继续!先把两个 void 方法改造一下

 async static Task DoWork(string workerName)
{
await Task.Delay();
Console.WriteLine("{0} is working @ Thread Id {1}", workerName, System.Threading.Thread.CurrentThread.ManagedThreadId);
} async static Task DoClean(string cleaner)
{
await Task.Delay();
Console.WriteLine("{0} is cleaning @ Task Id {1}", cleaner, Task.CurrentId);
}

变成了 Task 的方法,就有了控制的前提条件,接下来改造一下 ContinueWith 的流程

 {
var taskWorker = Task.Factory.StartNew(() => DoWork("工作者1"));
await taskWorker.Result;
var c1 = await taskWorker.ContinueWith(backer => DoClean("清理者1"), TaskContinuationOptions.OnlyOnRanToCompletion);
var c2 = await c1.ContinueWith(backer => DoClean("清理者2"), TaskContinuationOptions.OnlyOnRanToCompletion);
var c3 = await c2.ContinueWith(backer => DoClean("清理者3"), TaskContinuationOptions.OnlyOnRanToCompletion);
}

把原来写在一起的一堆 ContinueWith 分开,让它们各自“拥有身份”,并且按顺序去继承上一个 Task,只有当指定的 Task 执行完成到 RanToCompletion 的状态时自身才被启用,并且 await 的使用保证了 taskWorker 运行完成 C1 才会执行,C1 运行完 C2 才会执行,C2 运行完 C3 才会执行。到此,似乎实现了我们的要求。

.Net 异步随手记(二)的更多相关文章

  1. .Net 异步随手记(三)

    从<.Net 异步随手记(二)>来看,总感觉还差点儿什么,就是对不同情况的处理.比如当一个 Task 完成了后,我想让它继续执行 T1,如果被取消了就去执行 T2,如果...就去执行 T3 ...

  2. python异步IO编程(二)

    python异步IO编程(二) 目录 开门见山 Async IO设计模式 事件循环 asyncio 中的其他顶层函数 开门见山 下面我们用两个简单的例子来让你对异步IO有所了解 import asyn ...

  3. Javascript异步编程之二回调函数

    上一节讲异步原理的时候基本上把回掉函数也捎带讲了一些,这节主要举几个例子来具体化一下.在开始之前,首先要明白一件事,在javascript里函数可以作为参数进行传递,这里涉及到高阶函数的概念,大家可以 ...

  4. 异步编程(二)基于事件的异步编程模式 (EAP)

    一.引言 在上一个专题中为大家介绍了.NET 1.0中提出来的异步编程模式——APM,虽然APM为我们实现异步编程提供了一定的支持,同时它也存在着一些明显的问题——不支持对异步操作的取消和没有提供对进 ...

  5. ASP.NET Core 3.x启动时运行异步任务(二)

    这一篇是接着前一篇在写的.如果没有看过前一篇文章,建议先去看一下前一篇,这儿是传送门   一.前言 前一篇文章,我们从应用启动时异步运行任务开始,说到了必要性,也说到了几种解决方法,及各自的优缺点.最 ...

  6. C#异步编程(二)

    async和await结构 序 前篇博客异步编程系列(一) 已经介绍了何谓异步编程,这篇主要介绍怎么实现异步编程,主要通过C#5.0引入的async/await来实现. BeginInvoke和End ...

  7. 浅析Netty的异步事件驱动(二)

    上一篇文件浅析了Netty中的事件驱动过程,这篇主要写一下异步相关的东东. 首先,什么是异步了? 异步的概念和同步相对.当一个异步过程调用发出后,调用者不能立刻得到结果.实际处理这个调用的部件在完成后 ...

  8. .Net 异步随手记(一)

    今天要记录的内容摘要是: 什么时候异步代码能“等”在那里,什么时候不会“等” 这两天Coding的时候碰到一个事儿,就是想让异步等在那里结果却直接执行过去了,比如这样: async static vo ...

  9. django celery的分布式异步之路(二) 高并发

    当你跑通了前面一个demo,博客地址:http://www.cnblogs.com/kangoroo/p/7299920.html,那么你的分布式异步之旅已经起步了. 性能和稳定性是web服务的核心评 ...

随机推荐

  1. Compare .NET Objects对象比较组件

    Compare .NET Objects对象比较组件 阅读目录 1.Compare .NET Objects介绍 2. Compare .NET Objects注意事项 3.一个简单的使用案例 4.三 ...

  2. C#中利用双缓冲技术解决绘图闪屏问题。

    这段时间在做一个小型游戏,在界面显示的时候用到了一些图形.一开始涉及到的图形全都用控件的背景图片代替了.这样游戏运行的时候存在的一个很大的问题是游戏运行很慢.小组成员费尽周折,即将放弃,每一个成员都愁 ...

  3. 打破了中国电信华为无线路由猫(HG522-C)自己主动拨号+任意数量的计算机+iTV

    中国电信路由猫去势后总是我的好E家里到处都是卖包(够坏垄断市场.有霸王条款多,例如,他们必须用自己的手机,同时计算机的最大数量的在线等),我曾破获另一家中国电信路由猫.非常easy,由U它磁盘恢复默认 ...

  4. Metrics监控应用

    使用Metrics监控应用程序的性能   在编写应用程序的时候,通常会记录日志以便事后分析,在很多情况下是产生了问题之后,再去查看日志,是一种事后的静态分析.在很多时候,我们可能需要了解整个系统在当前 ...

  5. Apache & WebDav 配置(二)

    (二)WebDav配置 & put脚本编辑! WebDav 配置 ---------------- # 1. 修改了两个配置文件 # 2. 创建web访问用户的用户名和口令 # 3. 创建了两 ...

  6. 【百度地图API】关于如何进行城市切换的三种方式

    原文:[百度地图API]关于如何进行城市切换的三种方式 摘要:本文介绍了三种切换城市的方式:查询城市.城市列表和显示城市轮廓. ------------------------------------ ...

  7. leetcode -day31 Subsets I II

    1.  Subsets Given a set of distinct integers, S, return all possible subsets. Note: Elements in a ...

  8. 判断文件是否存在,不存在创建文件&&判断文件夹是否存在,不存在创建文件夹

    1.判断文件是否存在,不存在创建文件 File file=new File("C:\\Users\\QPING\\Desktop\\JavaScript\\2.htm"); if( ...

  9. jq toggle1.9版本后不支持解决方案

    <script type="text/javascript"> $(document).ready(function(){ $("button"). ...

  10. Mvc 导出 Excel

    Mvc 导出 Excel 之前接触过Webform,winfrom 的导出Excel方法 ,优点:省事.缺点:服务器必须安装Office 这几天做项目 和 大牛学习了一下 新的方法,自己加以总结.希望 ...