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 操作,可以查询计算是否完成,并且可以获取计算 的结果.结果 ...
随机推荐
- cookie,session原理,以及如何使用chrome查看。
首先,先补充下chrome浏览器的使用. 1.1.php源码: <?php $cookieDomain = '.elf.com'; setcookie(, '/', $cookieDomain) ...
- js如何找到方法在哪个js文件
在Console窗口中输入var f = methodA.prototype.constructor;console.log(f); 网络搜索到的方法.
- 【Java】:ehcache
ehcache是一个纯Java进程内缓存框架,是hibernate默认的Cacheprovider.(出自百度百科). 1. 快速2. 简单3. 多种缓存策略4. 缓存数据有两级:内存和磁盘,因此无需 ...
- Hadoop2.6.0的FileInputFormat的任务切分原理分析(即如何控制FileInputFormat的map任务数量)
前言 首先确保已经搭建好Hadoop集群环境,可以参考<Linux下Hadoop集群环境的搭建>一文的内容.我在测试mapreduce任务时,发现相比于使用Job.setNumReduce ...
- Maven 整合 spring profile实现多环境自动切换
Maven 整合 spring profile实现多环境自动切换 时间:2014-03-19 15:32来源:Internet 作者:Internet 点击:525次 profile主要用在项目多环境 ...
- hibernate配置文件中的schema="dbo"在MySQL数据库不可用
把项目的数据库由SQL Server更改为MySQL之后,发现hibernate报错. 问题在于schema="dbo",使用SQL Sever数据库时正常,使用MySQL数据库需 ...
- STL的迭代器和类型萃取
今天就可以把STL库中迭代器的实现,和类型萃取好好整理一下了 迭代器的设计思维是STL的关键所在,在STL的实际运用和泛型思维,迭代器都扮演着十分重要的角色,STL力求把数据容器和算法的概念分开来,于 ...
- C语言的选择和循环上机题目(部分)
/*(1)某市不同车牌的出租车3公里的起步价和计费分别为:夏利7元/公里,3公里以外2.1元/公里:富康8元/公里,3公里以外2.4元/公里:桑塔纳9元,3公里以外2.7元/公里.编程:从键盘输入乘车 ...
- Java 第22章 mySQy
下列都是关系型数据库(在数据库中存在行.列) oracle: Oracle公司的产品(被sun公司收购) 中大型项目使用.银行系统.政府办公系统 9i/10g/11g sql server: 微软公司 ...
- 一个日期的下一个星期五 next_date
select next_day('18-5月-2001','星期五') nxt_day from dual;