使用 Async 和 Await 的异步编程 #Reprinted#

异步方法容易编写

string urlContents = await client.GetStringAsync();

以下特征总结了使上面一个异步方法。

  • 方法签名包含一个 Async 或async 修饰符。
  • 异步方法的名称以“Async”后缀,按照约定,关闭。
  • 返回类型为下列类型之一:
    • Task<TResult>,如果您的方法具有操作个线程类型 TResult 的返回语句。
    • Task,如果方法没有返回语句或具有返回语句不操作。
    • 无效 (在 Visual Basic 中 ),如果您编写一个异步事件处理程序。
  • 方法通常包含至少一个等待表达式,指示个方法无法继续,直到该等待的异步操作完成的。同时,方法被挂起,并且,控件返回到方法的调用方。本主题的下一节将解释发生的悬挂点。

在异步方法,可以使用提供的关键字和类型指示要执行,因此,编译器执行方式,包括记录必须出现,当控件处于挂起的方法时回时间点。某些实例处理,例如循环,而异常处理,可能很难进行在传统异步代码的句柄。在异步方法,解决您编写这些元素,因为在一个同步解决方案会并将问题。

任何异步方法

若要了解的最重要的操作在异步编程是控制流如何从方法移动到方法。下图通过处理导致生成。

在关系图的数值对应于以下步骤。

说明:

  1. 事件处理程序调用并等待 AccessTheWebAsync 异步方法。
  2. AccessTheWebAsync 创建HttpClient 实例并调用GetStringAsync  异步方法下载网站内容作为字符串。
  3. 挂起团队进度的内容发生 GetStringAsync 发生。 可能必须等待网站下载或一些其他块的事件。若要避免妨碍资源,GetStringAsync 为控件对其调用方,AccessTheWebAsync。

    GetStringAsync返回 TResult 是字符串的Task<TResult>,并且,AccessTheWebAsync  将任务指派给getStringTask 变量。在工作完成时,任务表示继续对定向到GetStringAsync,以提交导致实际字符串值。

  4. 由于 getStringTask 不等待,AccessTheWebAsync 可以继续执行不依赖于从 GetStringAsync的最终结果的其他工作。 该任务由为同步方法DoIndependentWork的调用表示。
  5. DoIndependentWork 完成其工作并回调用方的同步方法。
  6. AccessTheWebAsync 用完了它可以完成,不会受到getStringTask的结果的工作。接下来AccessTheWebAsync 若要计算并返回该下载的字符串的长度,但是,该方法无法计算该值,直到该方法具有字符串。

    因此,AccessTheWebAsync 使用一个等待运算符挂起的进度并使控件到调用AccessTheWebAsync的方法。AccessTheWebAsync  返回Task(Of Integer) 或Task<int> 调用方。任务表示形式导致为下载的字符串的长度的整数结果。 (说明:如果GetStringAsync (并 getStringTask) 后,在AccessTheWebAsync 等待之前,控件在AccessTheWebAsync保持。成本挂起然后返回到AccessTheWebAsync 将浪费,如果异步调用过程 (getStringTask)  已经完成了,并且 AccessTheWebSync 不必等待最终结果。      在调用方 (在此示例中的事件处理程序内),处理重复。调用方可能完成不依赖于从AccessTheWebAsync 的结果在等待该结果之前的其他工作,或调用方可能立即等待。在事件处理程序到达等待表达式时,应用程序集中精力GetStringAsync的完成。事件处理程序等待AccessTheWebAsync,并且,AccessTheWebAsync  等待GetStringAsync。

  7. GetStringAsync完成并生成一个字符串结果。字符串结果不通过对GetStringAsync  的调用返回方式与您可能期望的。(请确保方法返回已在第 3 步 .) 的任务,字符串结果在表示方法的完成的任务,getStringTask存储。等待运算符从getStringTask检索结果。赋值语句将检索的结果赋给urlContents。
  8. GetStringAsync完成并生成一个字符串结果。字符串结果不通过对GetStringAsync  的调用返回方式与您可能期望的。(请确保方法返回已在第 3 步 .) 的任务,字符串结果在表示方法的完成的任务,getStringTask存储。等待运算符从getStringTask检索结果。赋值语句将检索的结果赋给urlContents。

如果您不熟悉异步编程,请需要一分钟考虑同步和异步行为之间的差异。一个同步方法返回,其工作完成 (第 5 步),但是,异步方法返回任务值,其工作挂起时 (第 3  步和第 6 步)。在异步方法最终完成其工作时,任务将会标记为已完成和结果,如果有,在任务中。

API 异步方法

在什么情况下可能想知道找到支持异步编程的方法 (如GetStringAsync。.NET Framework 4.5 包含与异步以及等待的许多成员。您可以通过附加到成员名称和Task  或Task<TResult>的返回类型“Async”后缀识别这些成员。例如,System.IO.Stream 选件类包含方法例如CopyToAsyncReadAsyncWriteAsync  在同步方法CopyToReadWrite

Windows 运行时 还包含您在 Windows 应用商店 apps 可以使用异步和等待的许多方法。

线程

异步方法旨在成为非阻塞操作。当等待的任务运行时,在异步方法的一个等待表达式不会阻止当前线程。相反,该表达式注册该方法的其余部分作为继续并返回控制对异步方法的调用方。

异步和等待关键字不会导致其他线程创建。因为异步方法本身并不会运行的线程,异步方法不需要多线程。只有 + 当方法处于活动状态,则方法在当前同步上下文中运行并使用在线程的时间。可以使用Task.Run  移动 CPU 工作移到后台线程,但是,后台线程不利于等待结果变得可用处理。

以异步编程的基于异步的方法优于于几乎每个用例的现有方法。具体而言,此方法比 IO 操作的BackgroundWorker  好,因为代码更为简单的,因此无需防止争用条件。与Task.Run的组合,异步编程的 CPU 操作的BackgroundWorker  好,因为异步编程从Task.Run 传输到线程池的工作分隔运行您的代码以协调详细信息。

异步和等待

如果指定使用 异步异步 修饰符,方法是异步方法,可以实现以下两个函数。

  • 清单异步方法可以使用 Await 或指定的 等待 悬挂点。等待运算符通知编译器异步方法不能继续点的过去,直到等待的异步过程完成。同时,控制权交还异步方法的调用方。

    一个异步方法的备用在等待表达式的不构成从方法的退出,并且,finally 块不会运行。

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

异步方法通常包含等待运算符的一个或多个匹配项,但是,请假等待表达式不会导致编译器错误。如果异步方法不会将等待运算符指示悬挂点,方法尽管"修饰符执行,一个同步方法。编译器会发出此类方法的警告。

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

返回类型和参数

在编程 .NET framework,异步方法通常返回TaskTask<TResult>。在异步方法中,等待运算符应用于从调用返回到另一个异步方法的任务。

您指定 Task<TResult>,因为返回类型,则方法包含指定类型TResult操作上的一个返回 (Visual Basic) 或返回 (c#) 语句。

使用 Task,因为返回类型,则该方法没有返回语句或具有不返回操作线程的 return 语句。

下面的示例演示如何声明并调用返回Task<TResult>Task的方法。

// Signature specifies Task<TResult>
02.async Task<int> TaskOfTResult_MethodAsync()
03.{
04.    int hours;
05.    // . . .
06.    // Return statement specifies an integer result.
07.    return hours;
08.}
09.
10.// Calls to TaskOfTResult_MethodAsync
11.Task<int> returnedTaskTResult = TaskOfTResult_MethodAsync();
12.int intResult = await returnedTaskTResult;
13.// or, in a single statement
14.int intResult = await TaskOfTResult_MethodAsync();
15.
16.
17.// Signature specifies Task
18.async Task Task_MethodAsync()
19.{
20.    // . . .
21.    // The method has no return statement.
22.}
23.
24.// Calls to Task_MethodAsync
25.Task returnedTask = Task_MethodAsync();
26.await returnedTask;
27.// or, in a single statement
28.await Task_MethodAsync();

每个返回的任务表示正在进行的工作。任务封装有关状态的信息异步过程和,最后,从进程的最终结果或处理引发的异常;如果未成功。

异步方法也是 Sub 方法 (Visual Basic) 或使 void 返回类型 (c# 中)。这将返回类型主要用于定义事件处理程序,void 返回类型需要。异步事件处理程序通常用作异步程序的起始点。

是 Sub 程序或具有 void 返回类型不能等待的异步方法和一个无效返回的方法的调用方无法捕获方法引发的任何异常。

异步方法不能声明在 Visual Basic 或refByRef 参数或在 C# 中http://msdn.microsoft.com/zh-cn/library/t3c3bfhx.aspx  参数,但是,方法可以调用具有这些参数的方法。

在 Windows 运行时 编程的异步 API 使之一返回类型,类似于任务:

命名约定

按照约定,您追加“Async”传递给具有Async 或async 修饰符方法的名称。

您可以忽略事件、基类或接口协定建议一个不同的名称约定。例如,您不应向常用事件处理程序重命名,例如Button1_Click。

相关主题


标题


描述


示例


演练:使用 Async 和 Await 访问 Web(C# 和 Visual Basic)


演示如何将同步 WPF 解决方法转换为异步 WPF 解决方案。 应用程序下载一系列网站。


Async 示例:访问 Web 演练 (C# 和 Visual Basic)


如何:使用 Task.WhenAll 扩展演练(C# 和 Visual Basic)


添加 Task.WhenAll 到上一个演练中。使用WhenAll  启动同时下载。

 

如何:并行发起多个 Web 请求(C# 和 Visual Basic)


演示如何同时启动几个任务。


Async 示例:并行生成多个 Web 请求 (C# 和 Visual Basic)


异步返回类型(C# 和 Visual Basic)


描述异步方法可能会返回的类型并解释每个类型时正确。

 

异步程序中的控制流(C# 和 Visual Basic)


跟踪控制流在连续详细在等待异步程序的表达式。


Async 示例:在异步程序的控制流 (C# 和 Visual Basic)


微调异步应用程序(C# 和 Visual Basic)


演示如何添加以下功能添加到的"解决方法:


Async 示例:优化应用程序 (C# 和 Visual Basic)


处理异步应用程序中的重入(C# 和 Visual Basic)


演示如何有效的异步操作重新启动的处理种情况下,在运行时。

 

WhenAny:.NET Framework 和 Windows 运行时之间的桥接(C# 和 Visual Basic)


演示如何消除在任务之间 .NET framework 和 IAsyncOperations 在 Windows 运行时,以便可以使用WhenAny 与 Windows 运行时 方法。


Async 示例:它们在 .NET 和窗口运行时 (AsTask 和 WhenAny)


取消:.NET Framework 和 Windows 运行时之间的桥接(C# 和 Visual Basic)


演示如何消除在任务之间 .NET framework 和 IAsyncOperations 在 Windows 运行时,以便可以使用CancellationTokenSource 与 Windows 运行时 方法。


Async 示例:它们在 .NET 和窗口运行时 (AsTask &取消)


使用 Async 以进行文件访问(C# 和 Visual Basic)


列出并演示如何使用异步的优点并等待访问文件。

 

演练:将调试器与异步方法一起使用


演示在等待语句的控制流,并演示 单步执行、逐过程和跳出 命令的行为在异步方法中。

 

基于任务的异步模式 (TAP)


描述 .NET framework 中 asynchrony 的新架构。 该模式根据 TaskTask<TResult>  类型。

 

快速入门:调用 c# 或 Visual Basic 中的异步 API


在 Windows 应用商店 app 演示如何使用异步和等待。

 

异步编程 (windows 存储 apps)


提供异步编程的概述 Windows 运行时。

 

在通道 9 的"视频


提供指向有关异步编程的各种视频。

完整的示例

下面的代码是从本主题讨论的 windows 演示基础 (WPF) 应用程序的 MainWindow.xaml.vb 或 MainWindow.xaml.cs 文件。可下载示例从Async  示例:从“异步编程的示例使用"和”等待

<span style="font-size: 14px;">using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;

// Add a using directive and a reference for System.Net.Http;
using System.Net.Http;

namespace AsyncFirstExample
{
    public partial class MainWindow : Window
    {
        // Mark the event handler with async so you can use await in it.
        private async void StartButton_Click(object sender, RoutedEventArgs e)
        {
            // Call and await separately.
            //Task<int> getLengthTask = AccessTheWebAsync();
            //// You can do independent work here.
            //int contentLength = await getLengthTask;

            int contentLength = await AccessTheWebAsync();

            resultsTextBox.Text +=
                String.Format("\r\nLength of the downloaded string: {0}.\r\n", contentLength);
        }

        // 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;
        }

        void DoIndependentWork()
        {
            resultsTextBox.Text += "Working . . . . . . .\r\n";
        }
    }
}

// Sample Output:

// Working . . . . . . .

// Length of the downloaded string: 41564.</span>

转载自:http://msdn.microsoft.com/zh-cn/library/hh191443.aspx   (中文地址)

http://msdn.microsoft.com/en-us/library/vstudio/hh191443.aspx (英文地址)

时间: 2024-10-09 21:16:08

使用 Async 和 Await 的异步编程 #Reprinted#的相关文章

【转】【C#】C# 5.0 新特性——Async和Await使异步编程更简单

一.引言 在之前的C#基础知识系列文章中只介绍了从C#1.0到C#4.0中主要的特性,然而.NET 4.5 的推出,对于C#又有了新特性的增加--就是C#5.0中async和await两个关键字,这两个关键字简化了异步编程,之所以简化了,还是因为编译器给我们做了更多的工作,下面就具体看看编译器到底在背后帮我们做了哪些复杂的工作的. 二.同步代码存在的问题 对于同步的代码,大家肯定都不陌生,因为我们平常写的代码大部分都是同步的,然而同步代码却存在一个很严重的问题,例如我们向一个Web服务器发出一个

Async和Await进行异步编程

使用Async和Await进行异步编程(C#版 适用于VS2015) 你可以使用异步编程来避免你的应用程序的性能瓶颈并且加强总体的响应.然而,用传统的技术来写异步应用是复杂的,同时编写,调试和维护都很困难. VS2012介绍了简单的方法,那就是异步编程,它在.Net Framework 4.5和Windows 运行时提供了异步支持.编译器做了开发者以前做的困难的工作,而且你的应用保持了类似于异步代码的逻辑结构.结果,你轻易地就获得了所有异步编程的优势. 异步提升响应 异步对于可能阻塞的活动是至关

使用Async和Await进行异步编程(C#版 适用于VS2015)

你可以使用异步编程来避免你的应用程序的性能瓶颈并且加强总体的响应.然而,用传统的技术来写异步应用是复杂的,同时编写,调试和维护都很困难. VS2012介绍了简单的方法,那就是异步编程,它在.Net Framework 4.5和Windows 运行时提供了异步支持.编译器做了开发者以前做的困难的工作,而且你的应用保持了类似于异步代码的逻辑结构.结果,你轻易地就获得了所有异步编程的优势. 异步提升响应 异步对于可能阻塞的活动是至关重要的.例如当你的应用访问Web的时候,访问web资源有时有点慢或者延

使用 Async 和 Await 的异步编程(C#)

本篇的内容大部分来自于同事的邮件描述,本想自己用言简意赅的用语言转述,无奈语言水平有限,且同事的介绍也是极尽详细和明了,故不再画蛇添足,直接引述.... 通过使用异步编程,你可以避免性能瓶颈并增强应用程序的总体响应能力.但是,编写异步应用程序的传统技术可能比较复杂,使它们难以编写.调试和维护. Visual Studio 2012 引入了一个简化的方法,异步编程,在 .NET Framework 4.5 和 Windows 运行时利用异步支持. 编译器可执行开发人员曾进行的高难度工作,且应用程序

使用Async和Await进行异步编程(C#版 适用于VS2015) z

你可以使用异步编程来避免你的应用程序的性能瓶颈并且加强总体的响应.然而,用传统的技术来写异步应用是复杂的,同时编写,调试和维护都很困难. VS2012介绍了简单的方法,那就是异步编程,它在.Net Framework 4.5和Windows 运行时提供了异步支持.编译器做了开发者以前做的困难的工作,而且你的应用保持了类似于异步代码的逻辑结构.结果,你轻易地就获得了所有异步编程的优势. 异步提升响应 异步对于可能阻塞的活动是至关重要的.例如当你的应用访问Web的时候,访问web资源有时有点慢或者延

使用 Async 和 Await 的异步编程(C# 和 Visual Basic)[msdn.microsoft.com]

看到Microsoft官方一篇关于异步编程的文章,感觉挺好,不敢独享,分享给大家. 原文地址:https://msdn.microsoft.com/zh-cn/library/hh191443.aspx 通过使用异步编程,你可以避免性能瓶颈并增强应用程序的总体响应能力. 但是,编写异步应用程序的传统技术可能比较复杂,使它们难以编写.调试和维护. Visual Studio 2012 引入了一个简化的方法(即异步编程),该方法利用 .NET Framework 4.5 和 Windows 运行时中

使用 Async 和 Await 的异步编程

来自:http://msdn.microsoft.com/library/vstudio/hh191443 异步对可能起阻止作用的活动(例如,应用程序访问 Web 时)至关重要. 对 Web 资源的访问有时很慢或会延迟. 如果此类活动在同步过程中受阻,则整个应用程序必须等待. 在异步过程中,应用程序可继续执行不依赖 Web 资源的其他工作,直至潜在阻止任务完成. 下表显示了异步编程提高响应能力的典型区域. 从 .NET Framework 4.5 和 Windows 运行时中列出的 API 包含

使用 Async 和 Await 的异步编程 MSDN

通过使用异步编程,你可以避免性能瓶颈并增强应用程序的总体响应能力. 但是,编写异步应用程序的传统技术可能比较复杂,使它们难以编写.调试和维护. Visual Studio 2012 引入了一个简化的方法,异步编程,在 .NET Framework 4.5 和 Windows 运行时利用异步支持. 编译器可执行开发人员曾进行的高难度工作,且应用程序保留了一个类似于同步代码的逻辑结构. 因此,你只需做一小部分工作就可以获得异步编程的所有好处. 中文MSDN地址 https://msdn.micros

C# Async和Await的异步编程例子

using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; using System.Windows; using System.Windows.Controls; using System.Windows.Data; using System.Windows.Documents; using System.Windows.I