首页 > 代码库 > 使用 Async 和 Await 的异步编程

使用 Async 和 Await 的异步编程

来自:http://msdn.microsoft.com/library/vstudio/hh191443
 
异步对可能起阻止作用的活动(例如,应用程序访问 Web 时)至关重要。 对 Web 资源的访问有时很慢或会延迟。 如果此类活动在同步过程中受阻,则整个应用程序必须等待。 在异步过程中,应用程序可继续执行不依赖 Web 资源的其他工作,直至潜在阻止任务完成。

下表显示了异步编程提高响应能力的典型区域。 从 .NET Framework 4.5 和 Windows 运行时中列出的 API 包含支持异步编程的方法。

 

应用程序区域

包含异步方法的受支持的 API

Web 访问

HttpClient ,SyndicationClient

使用文件

StorageFile、StreamWriter、StreamReader、XmlReader

使用图像

MediaCapture、BitmapEncoder、BitmapDecoder

WCF 编程

同步和异步操作

  

由于所有与用户界面相关的活动通常共享一个线程,因此,异步对访问 UI 线程的应用程序来说尤为重要。 如果任何进程在同步应用程序中受阻,则所有进程都将受阻。 你的应用程序停止响应,因此,你可能在其等待过程中认为它已经失败。

使用异步方法时,应用程序将继续响应 UI。 例如,你可以调整窗口的大小或最小化窗口;如果你不希望等待应用程序结束,则可以将其关闭。

当设计异步操作时,该基于异步的方法将自动传输的等效对象添加到可从中选择的选项列表中。 开发人员只需要投入较少的工作量即可使你获取传统异步编程的所有优点。

异步方法更容易编写

Visual Basic 中的 Async 和 Await 关键字,以及 C# 中的 async 和 await 关键字都是异步编程的核心。 通过使用这两个关键字,你可以使用 .NET framework 或 Windows 运行时中的资源轻松创建异步方法(几乎与创建同步方法一样轻松)。 通过使用被称为异步方法的 async 和 await 定义的异步方法。

下面的示例演示了一种异步方法。 你应对代码中的几乎所有内容都非常熟悉。 注释调出你添加的用来创建异步的功能。

 
// Three things to note in the signature://  - The method has an async modifier. //  - The return type is Task or Task<T>. (See "Return Types" section.)//    Here, it is Task<int> because the return statement returns an integer.//  - The method name ends in "Async."async Task<int> AccessTheWebAsync(){     // You need to add a reference to System.Net.Http to declare client.    HttpClient client = new HttpClient();    // GetStringAsync returns a Task<string>. That means that when you await the    // task you‘ll get a string (urlContents).    Task<string> getStringTask = client.GetStringAsync("http://msdn.microsoft.com");    // You can do work here that doesn‘t rely on the string from GetStringAsync.    DoIndependentWork();    // The await operator suspends AccessTheWebAsync.    //  - AccessTheWebAsync can‘t continue until getStringTask is complete.    //  - Meanwhile, control returns to the caller of AccessTheWebAsync.    //  - Control resumes here when getStringTask is complete.     //  - The await operator then retrieves the string result from getStringTask.    string urlContents = await getStringTask;    // The return statement specifies an integer result.    // Any methods that are awaiting AccessTheWebAsync retrieve the length value.    return urlContents.Length;}

 

如果 AccessTheWebAsync 在调用 GetStringAsync 和等待其完成期间不能进行任何工作,则你可以通过在下面的单个语句中调用和等待来简化代码。

 

API 异步方法
你可能想知道从何处可以找到 GetStringAsync 等支持异步编程的方法。 .NET Framework 4.5 包含使用 async 和 await 的许多成员。 可以通过附加到成员名称的“Async”后缀和 Task或 Task<TResult> 的返回类型识别这些成员。 例如,System.IO.Stream 类包含的方法 CopyToAsync、ReadAsync、WriteAsync 等方法以及同步方法 CopyTo、Read 和 Write。

 

线程
      如果通过使用 Async 或 async 修饰符指定某种方法为异步方法,则可以启用以下两个功能。
  • 标记的异步方法可以使用 Await 或 await 来指定悬挂点。 await 运算符通知编译器异步方法只有直到等待的异步过程完成才能继续通过该点。 同时,控件返回至异步方法的调用方。

    await 表达式中异步方法的挂起不能使该方法退出,并且 finally 块不会运行。

  • 标记的异步方法本身可以通过调用它的方法等待。

异步方法通常包含 await 运算符的一个或多个匹配项,但缺少 await 表达式不会导致编译器错误。 如果异步方法未使用 await 运算符标记悬挂点,则该方法将作为同步方法执行,不管异步修饰符如何。 编译器将为此类方法发布一个警告。

Async 、async、Await 和 await 都是上下文关键字。 

使用 Async 和 Await 的异步编程