C#高级编程第11版 - 第十五章

导航

15 Asynchronous Programming

15.1 异步编程的重要性

.NET Framework4.5新增了并行库(Task Parallel Library,TPL),使得.NET进行并行编程更加的简单。C# 5.0新增了两个关键字:async和await,使得异步编程也不再是难事。本章主要关注async和await的使用。

在异步编程中,一个方法调用是在后台运行的(往往是通过某个任务或者线程的帮助),而调用方所在的线程不会被挂起或者阻塞(not blocked)。

通过学习本章,你可以了解到不同模式的差异,如异步模式(asynchronous pattern),基于事件的异步模式(event-based asynchronous pattern),基于任务的异步模式(task-based asynchronous pattern,TAP)。在TAP中用到了async和await。当你比较这些不同的模式时,你就会发现异步编程真正的优势。

讨论完不同的模式之后,你将会通过创建任务和调用异步方法,学习到异步编程的基础组成。你将会了解到那些隐藏在后续任务(continuation tasks)和异步上下文之间的细节。

需要重点强调的是Error的处理;因为在不同的异步任务中,同样的应用场景需要一些不同的错误处理。

本章最后一部分将讨论Universal Windows App在异步编程中的应用场景以及需要注意的内容。

注意:任务和并行编程将在第21章进行介绍。

当你的应用程序动不动就未响应时,用户会很觉得很烦。虽然在使用鼠标的时候,我们已经习惯了它会有一点小小的延迟,因为我们已经用了它许多年了。但是在触摸式UI中,一个App需要对请求马上做出响应。否则,用户会试图来回碰触(redo the action)。

因为在古老版本的.NET Framework中异步编程很难实现,所以它常常达不到预期的目标。在旧版本的Visual Studio中,经常有一个应用程序会阻塞UI线程。在那种情况下,假如你要打开一个拥有数百个项目的解决方案,将花费相当长的时间(take a long coffee break)。VS2017提供了轻量级的解决方案加载特性,只有当项目需要被用到时才会进行加载,而且,选中的项目会被优先加载。从VS2015开始,NuGet包管理器不再作为一个对话框形式实现。新的NuGet包管理器可以在你进行其他操作的时候,异步加载包信息。这些只是Visual Studio里关于异步编程的一些重要的示例。

.NET的很多API都提供了同步和异步版本。因为同步版本的方法更加容易使用,所以它经常会在不合适的地方被调用。通过新的Windows运行时(Windows Runtime,WinRT),如果一个API调用超过40毫秒,只有它的异步版本是有效的。从C# 5.0开始,异步编程开始变得越来越容易,就跟同步的方式一样,所以使用异步API不需要有任何负担。当然异步API中也有不少坑(traps),本章也会一一介绍。

15.2 异步编程的.NET 历史

在开始使用新的async和await关键字之前,最好先了解一下.NET Framework曾经的异步编程模式。早在.NET Framework 1.0的时候,就已经有了异步的特性,并且.NET Framework中的许多基础类都支持不止一种异步编程模式。

扫描二维码关注公众号,回复: 9851417 查看本文章

这里,我们主要通过下面的三种方式来执行一个同步的网络请求(synchronous networking call):

  • 异步模式(asynchronous pattern)
  • 基于事件的异步模式(event-based asynchronous pattern)
  • 基于任务的异步模式(task-based asynchronous pattern,TAP)

异步模式是最初的异步处理特性,不单只支持一系列的API,还支持基础功能,如delegate类型。

因为使用异步模式更新UI非常的复杂——不管是通过Windows Forms还是WPF,.NET 2.0开始推荐使用基于事件的异步模式。在这个模式下,控制同步上下文的线程会调用一个事件处理器(event handler),所以这个模式下更新UI会很简单。先说一下,这个模式也被成为异步组件模式(asynchronous component pattern)。

通过.NET Framework 4.5,你可以使用另外一种异步编程的方式,TAP。这种模式基于Task类型,通过使用关键字async和await的编译器特性,来支持异步处理。

示例代码HistorySample使用了至少C# 7.1以上的特性以及下面列出的这些命名空间:

  • System
  • System.IO
  • System.Net
  • System.Threading.Tasks

15.2.1 同步调用

15.2.2 异步模式 313

15.2.3 基于事件的异步模式 314

15.2.4 基于任务的异步模式 314

15.2.5 异步Main()方法 315

15.3 异步编程的基础 315

15.3.1 创建任务 316

15.3.2 调用异步方法 316

15.3.3 使用Awaiter 317

15.3.4 延续任务 317

15.3.5 同步上下文 318

15.3.6 使用多个异步方法 318

15.3.7 使用ValueTasks 319

15.3.8 转换异步模式 320

15.4 错误处理 320

15.4.1 异步方法的异常处理 321

15.4.2 多个异步方法的异常处理 321

15.4.3 使用AggregateException 信息 322

15.5 异步与Windows 应用程序 322

15.5.1 配置await 323

15.5.2 切换到UI 线程 324

15.5.3 使用IAsyncOperation 325

15.5.4 避免阻塞情况 325

15.6 小结 325

猜你喜欢

转载自www.cnblogs.com/zenronphy/p/12501609.html