最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

關(guān)于async和await的一些誤區(qū)實(shí)例詳解

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

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

先舉一個(gè)示例代碼如下:

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");
 }
}

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

其實(shí)這個(gè)理解是錯(cuò)誤的。async和await的本質(zhì)其實(shí)是“yield return”和“LINQ”的“迭代式”等待。我們應(yīng)該清楚一點(diǎn):那就是你寫了LINQ語句:

var results = from ……
       select ……;

foreach(var r in results)
{
 ……
}

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

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

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

我們進(jìn)一步可以這樣對比:

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

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

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

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

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

var results = (from ……
              select ……).ToList();
因?yàn)榱⒓词褂玫搅诉@個(gè)LINQ語句,所以會(huì)被立即執(zhí)行。

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

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

因?yàn)镻rocessing本來就返回Task,當(dāng)然也可以使用Wait進(jìn)行同步等待。

相關(guān)文章

最新評論

平湖市| 定日县| 屏东县| 紫阳县| 北安市| 新昌县| 东辽县| 会昌县| 松滋市| 浮梁县| 阳春市| 郧西县| 东至县| 乌拉特后旗| 揭东县| 井冈山市| 兴山县| 岱山县| 开化县| 苗栗县| 广灵县| 保德县| 达州市| 苍南县| 大庆市| 东丽区| 宜君县| 施甸县| 图们市| 双鸭山市| 鄂伦春自治旗| 左权县| 桂东县| 鲜城| 米脂县| 盐源县| 肇东市| 博白县| 深水埗区| 峨眉山市| 鲜城|