Task:取消异步计算限制操作 & 捕获任务中的异常
Why:ThreadPool没有内建机制标记当前线程在什么时候完成,也没有机制在操作完成时获得返回值,因而推出了Task,更精确的管理异步线程。
How:通过构造方法的参数TaskCreationOptions控制如何创建任务,具体查看该枚举的枚举值。获取任务执行的结果有Task.Result属性,该属性内部调用wait(),例如WaitAny()、WaitAll()等等都可以。
如何取消异步计算限制操作呢?也就是说如何取消执行中的任务呢?(鄙视clr的作者用“计算限制操作”这么复杂的词汇。)
实例化CancelletionTokenSource类,把该对象作为参数传给异步方法,在异步方法中调用该对象的ThrowIfCancellationRequested(),如果该对象的Cancel()方法被调用了,那么异步方法就会抛出异常OperationCanceledException,在主线程用try-catch进行捕获(AggregateException),就可以捕获异常并进行处理。
class Program
{
static void Main(string[] args)
{
CancellationTokenSource cts = new CancellationTokenSource();//CancellationTokenSource(3000);//3秒后没有得到结果,则取消该线程。
Task<Int32> t1 = Task.Run(() => sum(cts.Token, 10000), cts.Token);//传入CancellationToken,它是CancellationTokenSource的属性。
cts.Cancel();//cts.CancelAfter(3000);//3秒后如果没有得到结果,则取消该线程。
try
{
Console.WriteLine("t1执行的结果是:" + t1.Result);//通过Result获取t1的执行结果。
}
catch (AggregateException ex)
{
ex.Handle(e => e is OperationCanceledException);
Console.WriteLine("sum已经被取消");
}
Console.ReadKey();
} private static int sum(CancellationToken ct, int p)
{
int sum = 0;
while (p > 0)
{
ct.ThrowIfCancellationRequested();
Thread.Sleep(500);//每隔半秒累加一次。
checked//如果区域内的计算溢出就会抛出异常
{
sum += p;
}
p--;
}
return sum;
}
}
运行结果:sum已经被取消
成功的捕获到了异常并处理了。
但是我发现有一个地方我不能理解
1、如果是通过CancellationTokenSource的构造方法public CancellationTokenSource(int millisecondsDelay);构造的实例对象,try-catch捕获不到异常。
2、如果是通过CanelAfter(TimeSpan delay)取消,也捕获不到异常。
通过ILSpy我发现上诉构造方法和CanelAfter方法都是调用Cancel()方法,但是为何捕获不到异常呢?
我进一步查看ThrowIfCancellationRequested源码
public void ThrowIfCancellationRequested()
{
if (this.IsCancellationRequested)
{
this.ThrowOperationCanceledException();
}
}
然而并没有什么卵用,因为只要把下图中的设置取消,即可捕获到了异常。
Task:取消异步计算限制操作 & 捕获任务中的异常的更多相关文章
- 编写高质量代码改善C#程序的157个建议——建议66:正确捕获多线程中的异常
建议66:正确捕获多线程中的异常 多线程的异常处理需要采用特殊的方式.一下这种方式会存在问题: try { Thread t = new Thread((ThreadStart)delegate { ...
- IOS异步和多线程操作&&在sqlite3中的应用
1,数据库I/O操作(异步) 数据库本身是存储在磁盘上.访问和修改数据库,即对磁盘进行读写,即I/O操作. 磁盘属于计算机硬件,具有DMA能力,不需要CPU干预,可以实现异步操作. I/O操作一般是消 ...
- 使用QFuture类监控异步计算的结果
版权声明:本文为博主原创文章,未经博主允许不得转载. https://blog.csdn.net/Amnes1a/article/details/65630701在Qt中,为我们提供了好几种使用线程的 ...
- 实践基于Task的异步模式
Await 返回该系列目录<基于Task的异步模式--全面介绍> 在API级别,实现没有阻塞的等待的方法是提供callback(回调函数).对于Tasks来说,这是通过像ContinueW ...
- 基于Task的异步模式的定义
返回该系列目录<基于Task的异步模式--全面介绍> 命名,参数和返回类型 在TAP(Task-based Asynchronous Pattern)中的异步操作的启动和完成是通过一个单独 ...
- 使用任务Task 简化异步编程
使用任务简化异步编程 Igor Ostrovsky 下载代码示例 异步编程是实现与程序其余部分并发运行的较大开销操作的一组技术. 常出现异步编程的一个领域是有图形化 UI 的程序环境:当开销较大的操作 ...
- 实现基于Task的异步模式
返回该系列目录<基于Task的异步模式--全面介绍> 生成方法 编译器生成 在.NET Framework 4.5中,C#编译器实现了TAP.任何标有async关键字的方法都是异步方法,编 ...
- Task的异步模式
Task的异步模式 返回该系列目录<基于Task的异步模式--全面介绍> 生成方法 编译器生成 在.NET Framework 4.5中,C#编译器实现了TAP.任何标有async关键字的 ...
- 13.FutureTask异步计算
FutureTask 1.可取消的异步计算,FutureTask实现了Future的基本方法,提供了start.cancel 操作,可以查询计算是否完成,并且可以获取计算 的结果.结果 ...
随机推荐
- 有关tp里搜索框的实现方法
1:
- prism4 StockTrader RI 项目分析一些体会2
prism 对于逻辑复杂的页面,通过建立 controller实现逻辑管理 按着一般的做法就是,各模块的viewmodel import由各模块去实例化(理解有限),但是通过controller实现了 ...
- 百度地图里面搜索到的公司商家电话导出表格?怎样将把百度地图里面搜索到的公司 电话 地址 等数据导出excel里?
好多人在问:如何将百度地图里面搜索到的公司商家电话导出表格?怎样将把百度地图里面搜索到的公司 电话 地址 等数据导出excel里? 现在,很多人都在网络上找商家,联系业务. 百度地图里有很多的商家联系 ...
- java单例模式实现方式
Singleton 模式要求一个类有且仅有一个实例,并提供一个全局访问点. Singleton模式 是一种职责型模式.因为我们创建了一个对象,这个对象扮演了独一无二的角色,在这个单独的对象实例中,它集 ...
- C#装箱和拆箱
1.装箱是将值类型转换为引用类型(或者转换为此值类型所实现的任何接口类型)的隐式转换,当 CLR 对值类型进行装箱时,会将该值包装到 System.Object 内部,再将后者存储在托管堆上. ; / ...
- OpenResty(nginx_lua_module)做ES代理以及备份ES数据
#user nobody; worker_processes 1; #error_log logs/error.log; #error_log logs/error.log notice; #erro ...
- [转]为什么使用 Redis及其产品定位
原文链接:http://www.infoq.com/cn/articles/tq-why-choose-redis 传统MySQL+ Memcached架构遇到的问题 实际MySQL是适合进行海量数据 ...
- iOS 选择的照片或者拍照的图片上添加日期水印
1..引入框架 #import "CLLocation+GPSDictionary.h"#import "NSDictionary+CLLocation.h" ...
- AutoVue ISDK学习总结(一)
这段时间,断断续续花了2,3周时间,研究AutoVue ISDK.貌似这个东西用的人很少,网上只搜到了一篇中文文档.自己英文水平差,Java水平也差,看Oracle官网文档,进展非常慢.到现在,终于对 ...
- PYTHON学习之路_PYTHON基础(8)
学习内容: Python模块介绍 1.经典类 or 新式类 2.抽象接口 3.静态方法.类方法.属性方法 4.反射 5.异常处理 6.socket编程初识 7.用socket实现get.put文件等功 ...