.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 括号里的部分不一定只在发 ...
随机推荐
- 移植X264成功
http://blog.csdn.net/mashang123456789/article/details/8673426 http://blog.csdn.net/b5w2p0/article/de ...
- Corel VideoStudio Pro X7(会声会影)
今天了解一天的视频剪辑方面的知识,自己也动手做了一个. 好啦!下面给大家一些建议: 剪辑软件选择: 1.易学易用.容易上手.模板丰富:会声会影:(需要安装包的可以留言和私信我)2.功能齐全.占用资源少 ...
- API接口开发 配置、实现、测试
Yii2 基于RESTful架构的 advanced版API接口开发 配置.实现.测试 环境配置: 开启服务器伪静态 本处以apache为例,查看apache的conf目录下httpd.conf,找到 ...
- java_OutOfMorryError 内存溢出(replaceAll)
最近在使用string类中的replaceAll函数时碰到这个错误,由于string长度比较长,文本文档9M多,可以增加jvm的内存大小解决. 下面是一篇对OutOfMorryError错误的一些处理 ...
- 去除win7 64位系统桌面图标小箭头
http://blog.csdn.net/pipisorry/article/details/24865195 在桌面新建一个文本文档 去除箭头.txt,把例如以下代码粘贴到文档中reg add &q ...
- 让Sqlite脱离VC++ Runtime独立执行
前段时间在开发OrayTalk(傲瑞通企业即时通信系统)的聊天记录模块时用到了Sqlite,这是我第一次接触和使用Sqlite,整体感觉还是很不错的.这里把我使用Sqlite的经验跟大家分享一下. 一 ...
- 开始 space viking 之旅
设备 cocos2d-v2 眼下cocos2d-v3也不太稳定,它在很大程度上仍然是变化的功能. 对于稳定.我们仍然使用 v2 wget -c http://cocos2d-iphone.goo ...
- IOS数组排序等
一.UITextField的代理方法 #pragma mark 当文本框开始编辑的时候调用---开始聚焦 - (void)textFieldDidBeginEditing:(UITextField * ...
- TML5安全:CORS(跨域资源共享)简介
来源:http://blog.csdn.net/hfahe/article/details/7730944 前言:像CORS对于现代前端这么重要的技术在国内基本上居然很少有人使用和提及,在百度或者Go ...
- MonkeyDevcie API 实践全记录
1. 背景 使用SDK自带的NotePad应用作为实践目标应用,目的是对MonkeyDevice拥有的成员方法做一个初步的了解. 以下是官方列出的方法的Overview. Return Type ...