欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

關于async和await的一些誤區(qū)實例詳解

 更新時間:2014年08月07日 15:37:14   投稿:shichen2014  
這篇文章主要介紹了關于async和await的一些誤區(qū)實例詳解,有助于更加深入的理解C#程序設計,需要的朋友可以參考下

微軟官方的MSDN上說async和await是“異步”,但是不少人(包括筆者自己)都有一些誤區(qū)需要澄清:為什么await語句之后沒有執(zhí)行?不是異步嗎?

先舉一個示例代碼如下:

public partial class Form1 : Form
{
 public async Task Processing()
 {
   await Task.Delay(5000);
   label1.Text = "Succuessful";
 }
 public Form1()
 {
   InitializeComponent();
   
 }
 private async void button1_Click(object sender, EventArgs e)
 {
   await Processing();
   MessageBox.Show("Button's event completed");
 }
}

很多人(包括筆者)一開始會覺得異步好像類似多線程一樣,到await的時候會在后臺先開啟一個線程執(zhí)行任務,隨后主線程(這里是UI線程)將自動執(zhí)行后面的部分(即彈出“Button's event completed”的消息框)。

其實這個理解是錯誤的。async和await的本質其實是“yield return”和“LINQ”的“迭代式”等待。我們應該清楚一點:那就是你寫了LINQ語句:

var results = from ……
       select ……;

foreach(var r in results)
{
 ……
}

當你下斷點你會發(fā)覺results并不會立即執(zhí)行,直到使用到results的地方(例子中也就是foreach這里)才會被執(zhí)行(此時黃色跟蹤調試的光棒又會折回到var results……這里,然后等到results執(zhí)行完畢之后才真正進入foreach進行執(zhí)行)。

所以,async/await和LINQ的這種“迭代式”的“異步操作”是異曲同工的。只不過async/await本質是返回一個Task而已,而Task又是異步的(因為Task本質就是一個線程),所以真正執(zhí)行到(使用到async方法的時候)帶有await的方法的時候,后臺才會真正開啟一個線程去執(zhí)行任務。此時主線程會等待這個Task線程直到其執(zhí)行完畢(IsComplete屬性為True為止)。所以界面是不會卡頓的。

所以,await是Task的異步等待而已,并不是我們所謂的“異步操作”;拿它和LINQ作對比,你會發(fā)現(xiàn)LINQ執(zhí)行順序和它一致,只不過LINQ沒有異步等待(當然沒有!又沒有開啟線程啥的……)。

我們進一步可以這樣對比:

LINQ:變量 = LINQ語句(表達式)

   等到使用LINQ變量的時候才折返到LINQ語句處真正執(zhí)行LINQ語句。

異步等待:變量 = 異步方法

    等到使用await+異步方法的時候才會折返到該異步方法處,開啟線程真正執(zhí)行異步方法,主線程被掛起(但不會造成界面死掉),直至子線程Task任務完全執(zhí)行完畢為止。

在LINQ中,你如果需要立即執(zhí)行,可以使用擴展方法:

var results = (from ……
              select ……).ToList();
因為立即使用到了這個LINQ語句,所以會被立即執(zhí)行。

同樣地,異步等待也可以變成類似Wait一樣的同步等待:

private async void button1_Click(object sender, EventArgs e)
{
  Processing().GetAwaiter().GetResult();
  MessageBox.Show("Button's event completed");
}

因為Processing本來就返回Task,當然也可以使用Wait進行同步等待。

相關文章

  • C#使用Clipboard類實現(xiàn)剪貼板功能

    C#使用Clipboard類實現(xiàn)剪貼板功能

    這篇文章介紹了C#使用Clipboard類實現(xiàn)剪貼板功能的方法,文中通過示例代碼介紹的非常詳細。對大家的學習或工作具有一定的參考借鑒價值,需要的朋友可以參考下
    2022-06-06
  • C#中調用Servlet示例

    C#中調用Servlet示例

    這篇文章主要介紹了C#中調用Servlet示例,本文實現(xiàn)通用消息接口使用servlet作為服務器端服務接口,第三方應用程序通過http post的方式調用servlet,實現(xiàn)與通用消息接口的調用連接,需要的朋友可以參考下
    2015-05-05
  • C#中Dictionary泛型集合7種常見的用法

    C#中Dictionary泛型集合7種常見的用法

    本文主要介紹了Dictionary集合的7種最基礎的用法,包括創(chuàng)建、添加、查找、遍歷、刪除等方法,程序都是由簡入繁,希望能通過閱讀簡單的示例,給大家一些啟發(fā)。
    2016-03-03
  • C#實現(xiàn)Winform無邊框移動的方法

    C#實現(xiàn)Winform無邊框移動的方法

    這篇文章主要介紹了C#實現(xiàn)Winform無邊框移動的方法,涉及C#針對WinForm窗口操作的相關技巧,具有一定參考借鑒價值,需要的朋友可以參考下
    2015-09-09
  • C#泛型用法實例分析

    C#泛型用法實例分析

    這篇文章主要介紹了C#泛型用法,實例分析了C#泛型的功能、定義與使用技巧,需要的朋友可以參考下
    2015-06-06
  • C#9特性record 類型、模式匹配、init 屬性詳情

    C#9特性record 類型、模式匹配、init 屬性詳情

    這篇文章主要介紹了C#的record 類型、模式匹配(Pattern Matching)、屬性的 init 訪問器三大特性,感興趣的小伙伴請參考下面文章內容
    2021-09-09
  • C#實現(xiàn)簡單的loading提示控件實例代碼

    C#實現(xiàn)簡單的loading提示控件實例代碼

    本文通過實例代碼給大家介紹了C#實現(xiàn)簡單的loading提示控件功能,代碼非常簡單,具有參考借鑒價值,需要的朋友參考下吧
    2017-09-09
  • C# 使用AE獲取feature的屬性及字段操作

    C# 使用AE獲取feature的屬性及字段操作

    這篇文章主要介紹了C# 使用AE獲取feature的屬性及字段操作,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧
    2021-01-01
  • C#多線程中的異常處理操作示例

    C#多線程中的異常處理操作示例

    這篇文章主要介紹了C#多線程中的異常處理操作,涉及C#多線程及異常的捕獲、處理等相關操作技巧,需要的朋友可以參考下
    2019-05-05
  • C#實現(xiàn)簡易的加密、解密字符串工具類實例

    C#實現(xiàn)簡易的加密、解密字符串工具類實例

    這篇文章主要介紹了C#實現(xiàn)簡易的加密、解密字符串工具類,涉及C#字符串加密與加密的實現(xiàn)技巧,具有一定參考借鑒價值,需要的朋友可以參考下
    2015-08-08

最新評論