zoukankan      html  css  js  c++  java
  • Async_Await;

    async关键字只是激活了await关键字,在遇到“await”关键字方法都是同步运行的。await 表达式表示可等待是一个异步操作点,在该点上,直到等待的异步操作完成方法才能继续(返回之前的“上下文”中执行),然后从异步方法返回。 在该点同时,将方法挂起,并且返回一个对象到方法的调用方!

    示例:原文(PS 我学习都是照着msdn文档打一遍的):https://msdn.microsoft.com/zh-cn/library/hh873191(v=vs.120).aspx

     1 using System;
     2 using System.Collections.Generic;
     3 using System.Linq;
     4 using System.Text;
     5 using System.Threading.Tasks;
     6 using System.Windows;
     7 using System.Windows.Controls;
     8 using System.Windows.Data;
     9 using System.Windows.Documents;
    10 using System.Windows.Input;
    11 using System.Windows.Media;
    12 using System.Windows.Media.Imaging;
    13 using System.Windows.Navigation;
    14 using System.Windows.Shapes;
    15 
    16 // Add a using directive and a reference for System.Net.Http; 
    17 using System.Net.Http;
    18 
    19 namespace AsyncTracer
    20 {
    21     public partial class MainWindow : Window
    22     {
    23         public MainWindow()
    24         {
    25             InitializeComponent();
    26         }
    27 
    28         private async void startButton_Click(object sender, RoutedEventArgs e)
    29         {
    30             // The display lines in the example lead you through the control shifts.
    31             resultsTextBox.Text += "ONE:   Entering startButton_Click.
    " +
    32                 "           Calling AccessTheWebAsync.
    ";
    33 
    34             Task<int> getLengthTask = AccessTheWebAsync();
    35 
    36             resultsTextBox.Text += "
    FOUR:  Back in startButton_Click.
    " +
    37                 "           Task getLengthTask is started.
    " +
    38                 "           About to await getLengthTask -- no caller to return to.
    ";
    39 
    40             int contentLength = await getLengthTask;
    41 
    42             resultsTextBox.Text += "
    SIX:   Back in startButton_Click.
    " +
    43                 "           Task getLengthTask is finished.
    " +
    44                 "           Result from AccessTheWebAsync is stored in contentLength.
    " +
    45                 "           About to display contentLength and exit.
    ";
    46 
    47             resultsTextBox.Text +=
    48                 String.Format("
    Length of the downloaded string: {0}.
    ", contentLength);
    49         }
    50 
    51 
    52         async Task<int> AccessTheWebAsync()
    53         {
    54             resultsTextBox.Text += "
    TWO:   Entering AccessTheWebAsync.";
    55 
    56             // Declare an HttpClient object.
    57             HttpClient client = new HttpClient();
    58 
    59             resultsTextBox.Text += "
               Calling HttpClient.GetStringAsync.
    ";
    60 
    61             // GetStringAsync returns a Task<string>. 
    62             Task<string> getStringTask = client.GetStringAsync("http://msdn.microsoft.com");
    63             //如果不需要显示这些文字,上面就可以直接await;await会阻塞本方法;
    64             resultsTextBox.Text += "
    THREE: Back in AccessTheWebAsync.
    " +
    65                 "           Task getStringTask is started.";
    66 
    67             // AccessTheWebAsync can continue to work until getStringTask is awaited.No await No asynchronous;
    68            
    69             resultsTextBox.Text +=
    70                 "
               About to await getStringTask and return a Task<int> to startButton_Click.
    ";
    71 
    72             // Retrieve the website contents when task is complete. 
    73             string urlContents = await getStringTask;
    74 
    75             resultsTextBox.Text += "
    FIVE:  Back in AccessTheWebAsync." +
    76                 "
               Task getStringTask is complete." +
    77                 "
               Processing the return statement." +
    78                 "
               Exiting from AccessTheWebAsync.
    ";
    79 
    80             return urlContents.Length;
    81         }
    82     }
    83 }

    执行结果:

    ONE:   Entering startButton_Click.
               Calling AccessTheWebAsync.
    
    TWO:   Entering AccessTheWebAsync.
               Calling HttpClient.GetStringAsync.
    
    THREE: Back in AccessTheWebAsync.
               Task getStringTask is started.
               About to await getStringTask & return a Task<int> to startButton_Click.
    
    FOUR:  Back in startButton_Click.
               Task getLengthTask is started.
               About to await getLengthTask -- no caller to return to.
    
    FIVE:  Back in AccessTheWebAsync.
               Task getStringTask is complete.
               Processing the return statement.
               Exiting from AccessTheWebAsync.
    
    SIX:   Back in startButton_Click.
               Task getLengthTask is finished.
               Result from AccessTheWebAsync is stored in contentLength.
               About to display contentLength and exit.
    
    Length of the downloaded string: 33946.
    

    跟踪程序:

    步骤一和二
     当 startButton_Click 调用 AccessTheWebAsync,且 AccessTheWebAsync 调用异步 HttpClient 方法 GetStringAsync(String) 时,前两个显示行跟踪该路径。 下图概述了从方法到方法的调用。

    AccessTheWebAsync 和 client.GetStringAsync 的返回类型是 Task 对于 AccessTheWebAsync,TResult 是整数。 对于GetStringAsync,TResult 是字符串。所以说await异步等待的方法跟此方法返回的类型可以不同; 当控件转换回调用方时,任务返回的异步方法返回任务实例。 当调用方法中出现 Await 或 await 运算符,或当调用方法结束时,控件从异步方法返回其调用方。 

    步骤三:

    在 AccessTheWebAsync 中,调用异步方法 GetStringAsync(String) 可下载目标网页的内容。 控件从 client.GetStringAsync 返回到AccessTheWebAsync,当 client.GetStringAsync 返回。

    client.GetStringAsync 方法返回分配给 AccessTheWebAsync 中 getStringTask 变量的字符串的任务。

    Task<string> getStringTask = client.GetStringAsync("http://msdn.microsoft.com");  

    您可以将任务视为 client.GetStringAsync 做出的承诺,以便最终生成一个实际字符串。 同时,如果 AccessTheWebAsync 要执行不依赖client.GetStringAsync 承诺的字符串的工作(也是下面的代码如果跟client.GetStringAsync返回的结果无关,不必await等待,执行完再await),则该工作在 client.GetStringAsync 等待时继续。 在示例中,以下输出行(标记为“THREE”)表示可以单独操作。

    THREE: Back in AccessTheWebAsync.
               Task getStringTask is started.
               About to await getStringTask & return a Task<int> to startButton_Click.
    

      当等待 getStringTask 时,下面的语句会挂起 AccessTheWebAsync 中的进程。调用方继续执行,直至遇到await;

    string urlContents = await getStringTask;
    

    下图显示了从 client.GetStringAsync 到 getStringTask 的分配和从 getStringTask 的创建到等待运算符的应用程序的控制流。

     

    重点:等待表达式挂起 AccessTheWebAsync 直到 client.GetStringAsync 返回。 同时,控件返回至 AccessTheWebAsync、startButton_Click 的调用方。

    步骤四:

    AccessTheWebAsync 的声明的返回类型是Task<int>。 因此,当 AccessTheWebAsync 挂起时,它向 startButton_Click 返回整数任务。 你应了解返回的任务并不是 getStringTask。 返回的任务是表示挂起的方法中仍要执行的整数的新任务 AccessTheWebAsync。 当任务完成时,任务是 AccessTheWebAsync 中的一个承诺以生成整数。
    主调用方的下面的语句将此任务分配给 getLengthTask 变量。
    Task<int> getLengthTask = AccessTheWebAsync();
    

      正如在 AccessTheWebAsync 中,startButton_Click 可继续那些不依赖于异步任务结果的工作 (getLengthTask) 直到任务处于等待状态。 下面的输出行表示该工作。

    FOUR:  Back in startButton_Click.
               Task getLengthTask is started.
               About to await getLengthTask -- no caller to return to.
    当 getLengthTask 等待时,startButton_Click 中的进程将被挂起。 下面的赋值语句会挂起 startButton_Click 直到 AccessTheWebAsync 完成。
    int contentLength = await getLengthTask;
    

    在下图中,箭头显示从 AccessTheWebAsync 中的 await 表达式到赋值给 getLengthTask 的控制流,接着是在 startButton_Click 中进行一般处理,直到等待 getLengthTask。

    步骤五:

    如果 client.GetStringAsync 发出了已完成信号,AccessTheWebAsync 中的处理过程就可以从挂起中释放并继续到 await 语句后。 输出的以下行表示处理的恢复。

    FIVE:  Back in AccessTheWebAsync.
               Task getStringTask is complete.
               Processing the return statement.
               Exiting from AccessTheWebAsync.
    

    返回语句 urlContents.Length 的操作存储在 AccessTheWebAsync 返回的任务中。 等待表达式从 startButton_Click 中的 getLengthTask 检索该值。

    下图显示 client.GetStringAsync(和 getStringTask)完成后的控件传输。

    如果 AccessTheWebAsync 发出了已完成信号,处理过程就可以继续到 startButton_Async中的 await 语句后。 实际上,程序没有其他要执行的操作。

    输出的以下行表示 startButton_Async 中处理的恢复:

    SIX:   Back in startButton_Click.
               Task getLengthTask is finished.
               Result from AccessTheWebAsync is stored in contentLength.
               About to display contentLength and exit.
    

    等待表达式是从作为 AccessTheWebAsync 中返回语句的操作数的 getLengthTask 整数值中检索的。 下面的语句将该值分配给 contentLength变量。

    int contentLength = await getLengthTask;
    

    下图显示了从 AccessTheWebAsync 到 startButton_Click 的控制返回。

  • 相关阅读:
    【读书笔记】【深入理解ES6】#13-用模块封装代码
    【读书笔记】【深入理解ES6】#12-代理(Proxy)和反射(Reflection)API
    【读书笔记】【深入理解ES6】#11-Promise与异步编程
    【读书笔记】【深入理解ES6】#10-改进的数组功能
    【读书笔记】【深入理解ES6】#9-JavaScript中的类
    【读书笔记】【深入理解ES6】#7-Set集合和Map集合
    【读书笔记】【深入理解ES6】#6-Symbol和Symbol属性
    关于maven打包文件不全的处理方式
    关于Dubbo的常用模型
    Dubbo源码本地运行demo遇到的问题
  • 原文地址:https://www.cnblogs.com/entclark/p/8232931.html
Copyright © 2011-2022 走看看