任务并行库

简介: 之前我们说了线程池和线程以及运用。

带着问题去思考!大家好!

简介

之前我们说了线程池和线程以及运用。实际上可以理解为他只是一个抽象层,其向程序员隐藏了使用线程的细节。但是使用线程池也是相当复杂,接着我们运用异步编程模型和基于事件的异步模式,这样获取结果很容易,传播异常也很轻松,但是组合多个异步操作仍然需要大量的工作,所以在.NET Framework 4.5引入了一个新的异步操作的API,任务并行库(Task).随之下一个版本进行更新。

APM API转换为任务

首先我们要知道什么是APM模式。

.net 1.0时期就提出的一种异步模式,并且基于IAsyncResult接口实现BeginXXX和EndXXX类似的方法。

View Code

这里我们定义两个委托,其中一个使用了OUT参数,因此再将APM模式转换为任务时,与标准的TPL API是不兼容的。

将APM转换为TPL的关键点是Task<T>.Factory.FromAsync方法,T是异步操作结果是类型。该方法有数个重载。在第一例子中传入了IAsyncResult和Func<IAsyncResult,string>,这是一个将IAsyncResult的实现参数并返回一个字符串的方法。由于第一个委托提供的EndMethod与该签名是兼容的,所以将该委托的异步调用转换为任务是可以的。

第二个例子与第一个非常相似,使用了不同的FromAsync方法重载,该重载并不允许指定一个将会在异步委托调用完成后被调用的回调函数,但我们可以使用后续操作替代它,但如果回调函数很重要,可以使用第一个例子的方法。

最后一个例子展示了一个小技巧,这次IncompatibleAsynchronousTask委托的EndMethod使用了out参数。与FromAsync方法并不兼容。然而,可以很容易的将EndMethod调用封装到一个lambda表达式中,从而适合任务工厂方法。

第一个任务状态为:WaitingForActivation,这意味TPL基础设施实际上还为启动任务

image.png

image.png

实现取消

基于任务的异步操作实现取消流程。我们将学习如果正确的使用取消标志,以及在任务真正运行前如何得知其他是否被取消。

image.png

这里我们所以说的为TPL任务实现取消选择的例子

首先仔细看看longTask的创建代码。我们将底层任务传递一次取消标志,然后给任务构造函数再传递一次,为什么需要提供取消标志两次呢?

是这样的;如果在任务实际启动前取消它,该任务的TPL基础设施有责任处理该取消操作。因为这些代码根本不会执行,通过得到的第一个任务的状态可以知道它被取消了。如果尝试堆该任务调用Start方法,将会得到InvalidOperationException异常。

然后需要自己写代码来处理取消过程,这意味着我们对取消过程全权负责,并且在取消任务后,任务的状态仍然是RanToCompletion,因为从TPL的视角来看,该任务正常完成了它的工作。辨别这两种情况是很重要的,并且需要理解每种情况下职责的不同。

处理任务中的异常

抛出异常的不同情况

image.png

当程序启动时,创建一个任务并尝试同步获取任务结果。Result属性的Get部分会使当前线程等待直到该任务完成并将异常传播给当前线程。这种情况下,通过catch代码块可以很容易的捕获异常,但是异常是一个被封装的异常。叫做AggregateException。在这个例子中,它里面包含一个异常,因为只有一个任务抛出异常。可以访问InnerException属性来得到底层异常。

第二个例子与第一个例子相似,不同的是使用了GetAwaiter和GetResult方法来访问任务结果。这种情况下,无需封装异常,因为TPL基础设施会提取该异常。如果只有一个底层任务,那么一次只能获取一个原始异常,这种设计非常合适

最后一个例子展示了两个任务抛出异常的情形,现在使用后续操作来处理异常。只有之前的任务完成前有异常时,该后续操作才会被执行。通过给后续操作传递TaskContinuationOptions.OnlyOnFaulted选项可以实现该行为。

 


相关文章
|
7月前
|
Linux Python
Python使用多进程并行加速业务操作 完整代码
Python使用多进程并行加速业务操作 完整代码
|
存储 消息中间件 安全
Python基于线程的并行和基于进程并行详解
当涉及到并行编程时,Python标准库提供了两种不同的方式:基于线程的并行(threading)和基于进程的并行(multiprocessing)。下面我将从概念、性能、使用场景和底层实现等方面对它们进行解释和比较。
175 0
|
SQL 中间件 PHP
Laravel 8 新特性之:迁移压缩、任务批处理、速率限制优化
Laravel 8 通过引入 Laravel Jetstream,模型工厂类,迁移压缩,队列批处理,改善速率限制,队列改进,动态 Blade 组件,Tailwind 分页视图, 时间测试助手,artisan serve 的改进,事件监听器的改进,以及各种其他错误修复和可用性改进,对 Laravel 7.x 继续进行了改善。
239 0
|
算法 调度
1_python高阶_线程—多任务(并发、并行)
1_python高阶_线程—多任务(并发、并行)
206 0
|
SQL 开发框架 算法
C#多线程开发-任务并行库04
C#多线程开发-任务并行库04
131 0
C#多线程开发-任务并行库04
|
存储 SQL 关系型数据库
并行查询的特性
并行查询可以说是PolarDB MySQL在计算层最为重要复杂度也最高的功能组件,随着PolarDB的推出已经线上稳定运行多年,而且一直在持续演进,它具备如下几个特性
99 0
|
并行计算 Java 数据挖掘
对于并行和并行概念上的理解与总结
并行和并行概念上的理解与总结
1103 0
|
消息中间件 并行计算 算法
用于并行图处理的 C++ 库libgrape-lite
libgrape-lite是阿里巴巴的一个 C++ 库,用于并行图处理。它与先前系统的不同之处在于,它能够通过遵循GRAPE的PIE编程模型将顺序图算法作为一个整体进行并行化。
用于并行图处理的 C++ 库libgrape-lite