.Net 异步随手记(三)
从《.Net 异步随手记(二)》来看,总感觉还差点儿什么,就是对不同情况的处理。比如当一个 Task 完成了后,我想让它继续执行 T1,如果被取消了就去执行 T2,如果...就去执行 T3,那怎么写呢?
过程是痛苦的,我笨了两天,终于搞通了。之前一直疑惑,为什么引发了 CancellationTokenSource 的 Cancel 方法,捕捉到的 Task 的 IsCanceled 属性依然是 False,今天晚上终于捕捉到了,看来还是自己写的有问题,不废话了,把代码记录一下:
namespace TaskConsole
{
class Program
{
static void Main(string[] args)
{
while (true)
{
var enter = Console.ReadLine(); if (enter.ToLower() == "continue")
{
cancelSource = new CancellationTokenSource();
token = cancelSource.Token;
var task = Entry();
Console.WriteLine(task.Status);
}
else if(enter.ToLower() == "cel") {
cancelSource.Cancel();
}
else { break; }
}
} async static Task DoWork(string workerName)
{
int count = ; while (count<)
{
if (token.IsCancellationRequested)
{
Console.WriteLine("用户主动取消了任务");
token.ThrowIfCancellationRequested();
} count++;
Console.WriteLine("{0} count {1} @ Thread Id {2}", workerName, count, System.Threading.Thread.CurrentThread.ManagedThreadId);
await Task.Delay();
}
} async static Task DoCancel(Task callbacker)
{
//await Task.Delay(2000);
Console.WriteLine("Do Cancel 任务运行了");
} async static Task DoContinue(Task callbacker)
{
//await Task.Delay(1000);
//Console.WriteLine("Continue 任务运行了 @ Task is {1}", callbacker.Status);
Console.WriteLine("Do Continue 运行了");
} async static Task Entry()
{
{
var taskWorker = Task.Factory.StartNew(() => DoWork("工作者1"));
try
{
await taskWorker.Result;
Console.WriteLine("taskworker 已经完成,是被取消的? {0}", taskWorker.Result.IsCanceled);
}
catch (OperationCanceledException)
{
Console.WriteLine("OperationCanceledException 异常,任务是被取消的? {0}", taskWorker.Result.IsCanceled);
} var c1 = taskWorker.Result.ContinueWith(backer => DoCancel(backer), TaskContinuationOptions.OnlyOnCanceled);
var c2 = taskWorker.Result.ContinueWith(backer => DoContinue(backer), TaskContinuationOptions.OnlyOnRanToCompletion);
}
} static CancellationTokenSource cancelSource;
static CancellationToken token;
}
}
从代码可以看出,C1 = 的是 taskWorker 的 Result 的 ContinueWith,也就是说,Token 真正引发的取消操作是作用于 DoWork 方法内的,而 taskWorker 并不是 DoWork 这个异步方法的引用,而是被 Factory“创建出来的某个运行 DoWork 的 Task”。因此,想要 C1、C2起作用,必须侦测的是 DoWork 方法到底是完成了还是被取消了,而 DoWork 方法是 taskWorker 的 Result,因此代码写成这样,运行结果就正确了。
输入 continue 启动程序,如果正常执行结束,将会是这样

中途输入 cel 来手动取消,将会是这样

感谢自己这脑袋终于想明白了,总结,如果写的是
var c1 = taskWorker.ContinueWith(backer => DoCancel(backer), TaskContinuationOptions.OnlyOnCanceled);
var c2 = taskWorkert.ContinueWith(backer => DoContinue(backer), TaskContinuationOptions.OnlyOnRanToCompletion);
那 C1 就永远不会有机会运行了,因为无论 DoWork 是正常结束还是被取消了,被工厂创建出来的那个 Task (也就是 taskWorker 所指向的对象)在 DoWork 返回之后都是 RanToCompletion。
.Net 异步随手记(三)的更多相关文章
- MVC异步AJAX的三种方法(JQuery的Get方法、JQuery的Post方法和微软自带的异步方法)
异步是我们在网站开发过程中必不可少的方法,MVC框架的异步方法也有很多,这里介绍三种方法: 一.JQuery的Get方法 view @{ Layout = null; } <!DOCTYPE h ...
- c#异步编程(三)—ASP.NET MVC 异步控制器及EF异步操作
ASP.NET MVC 异步控制器及EF异步操作 异步控制器 ASP.NET MVC2后开始了对异步请求管道的支持,异步请求管道的作用是允许web服务器处理长时间运行的请求,比如 那些花费大量时间等待 ...
- SpringBoot 异步线程简单三种样式
引用:在Java应用中,绝大多数情况下都是通过同步的方式来实现交互处理的:但是在处理与第三方系统交互的时候,容易造成响应迟缓的情况,之前大部分都是使用多线程来完成此类任务,其实,在Spring 3.x ...
- 异步解决方案(三)Promise
首先建议大家先看看这篇博文,这是我看过的最清晰给力的博文了: https://www.cnblogs.com/lvdabao/p/es6-promise-1.html 附赠一篇笑死我了的博客,加入有一 ...
- 【C# TAP 异步编程】三、async\await的运作机理详解
[原创] 本文只是个人笔记,很多错误,欢迎指出. 环境:vs2022 .net6.0 C#10 参考:https://blog.csdn.net/brook_shi/article/details/ ...
- Dart 异步编程(三):详细认识
基本概念 普通任务按照顺序执行:异步任务将在未来的某个时间执行. 实际演示 void main() { // waitFuture 函数是一个异步函数,阻塞会发生在函数内部 waitFuture(); ...
- .Net 异步随手记(一)
今天要记录的内容摘要是: 什么时候异步代码能“等”在那里,什么时候不会“等” 这两天Coding的时候碰到一个事儿,就是想让异步等在那里结果却直接执行过去了,比如这样: async static vo ...
- Python Flask后端异步处理(三)
前一篇博文我们已经将基础知识和环境配置进行了介绍:https://www.cnblogs.com/Cl0ud/p/13192925.html,本篇博文在实际应用场景中使用Celery,对Flask后端 ...
- .Net 异步随手记(二)
Task.ContinueWith 这货,和 await 一样有“陷阱”.^^,因为写 ContinueWith 不能直观如人的“过程性”思维,写在 ContinueWith 括号里的部分不一定只在发 ...
随机推荐
- HTTPS那个东西(一)-HTTPS原理
HTTPS那个东西(一) 最近看了<http权威指南>几个章节,对HTTPS随着节,了一些资料,遂打算记录一下心得.写的仓促,肯定有非常多错误的地方,欢迎大家指正. 1.HTTP是什么 那 ...
- cocos2dx 3.1.1移植安卓apk (lua交叉编译器项目 mac环境)
cocos2dx 3.1.1 lua项目安卓交叉编译 mac环境 本文基于ant,sdk,ndk,adt等软件和环境已经事前设置好 1\新建项目 在mac的终端下输入命令: cocos new t ...
- MongoDB详解学习历程
MongoDB是一个基于分布式文件存储的数据库,它是介于关系数据库和非关系数据库之间的产品. MongoDB支持的数据结构非常松散,类似json的bjson格式,因此可以存储比较复杂的数据类型.Mon ...
- DYNAMICRESOLUTION | NODYNAMICRESOLUTION
有时候开启OGG进程的时候较慢,可能是由于须要同步的表太多,OGG在开启进程之前会将须要同步的表建立一个记录而且存入到磁盘中,这样就须要耗费大量的时间.OGG同一时候也提供了DYNAMICRESOLU ...
- 从Access创建Sqlite数据库
首先,我们需要使用SQLite Expert Professional 工具 1.创建一个新的数据库 2.由SQLite Expert创建数据库.然后import --〉Data Transfer W ...
- 只显示年月的js时间控件 纯手写
<style> #date { text-align: center; } .td { cursor: pointer; } </style> <script> f ...
- MVC自定义分页
MVC自定义分页 之前我发表了一篇MVC无刷新分页的文章,里面用的是MvcPager控件,但是那个受那个控件限制,传值只能用PagedList,各方面都受到了限制,自由度不够高,现在还是做MVC无刷新 ...
- 安卓WindowManager注入事件如何跳出进程间安全限制
在分析monkey源码的时候有些背景知识没有搞清楚,比如在看到monkey是使用windowmanager的injectKeyEvent方法注入事件的时候,心里就打了个疙瘩,这种方式不是只能在当前应用 ...
- ASP.NET MVC局部视图
使用ASP.NET MVC局部视图避免JS拼接HTML,编写易于维护的HTML页面 以前使用ASP.NET WebForm开发时,喜欢使用Repeater控件嵌套的方式开发前台页面,这样就不用JS ...
- tornado settings想到的
今天有足够多的时间来看看Tornado中RequestHandler和Application这两个类的关系. 昨天想要调用settings中的内容,找了好半天不知道怎么在handler中使用setti ...