雷火电竞-中国电竞赛事及体育赛事平台

歡迎來到入門教程網(wǎng)!

C#教程

當前位置:主頁 > 軟件編程 > C#教程 >

淺談C#中的Async和Await的用法詳解

來源:本站原創(chuàng)|時間:2020-01-10|欄目:C#教程|點擊:

眾所周知C#提供Async和Await關(guān)鍵字來實現(xiàn)異步編程。在本文中,我們將共同探討并介紹什么是Async 和 Await,以及如何在C#中使用Async 和 Await。

同樣本文的內(nèi)容也大多是翻譯的,只不過加上了自己的理解進行了相關(guān)知識點的補充,如果你認為自己的英文水平還不錯,大可直接跳轉(zhuǎn)到文章末尾查看原文鏈接進行閱讀。

寫在前面

自從C# 5.0時代引入async和await關(guān)鍵字后,異步編程就變得流行起來。尤其在現(xiàn)在的.NET Core時代,如果你的代碼中沒有出現(xiàn)async或者await關(guān)鍵字,都會讓人感覺到很奇怪。

想象一下當我們在處理UI和按鈕單擊時,我們需要運行一個長時間運行的方法,比如讀取一個大文件或其他需要很長時間的任務(wù),在這種情況下,整個應(yīng)用程序必須等待這個長時間運行的任務(wù)完成才算完成整個任務(wù)。

換句話說,如果同步應(yīng)用程序中的任何進程被阻塞,則整個應(yīng)用程序?qū)⒈蛔枞?,我們的?yīng)用程序?qū)⑼V鬼憫?yīng),直到整個任務(wù)完成。

在這種情況下,異步編程將非常有用。通過使用異步編程,應(yīng)用程序可以繼續(xù)進行不依賴于整個任務(wù)完成的其他工作。

在Async 和 await關(guān)鍵字的幫助下,使得異步編程變得很簡單,而且我們將獲得傳統(tǒng)異步編程的所有好處。

實例講解

假設(shè)我們分別使用了兩種方法,即Method 1和Method 2,這兩種方法不相互依賴,而Method 1需要很長時間才能完成它的任務(wù)。在同步編程中,它將執(zhí)行第一個Method 1,并等待該方法的完成,然后執(zhí)行Method 2。因此,這將是一個時間密集型的過程,即使這兩種方法并不相互依賴。

我們可以使用簡單的多線程編程并行運行所有方法,但是它會阻塞UI并等待完成所有任務(wù)。要解決這個問題,我們必須在傳統(tǒng)編程中編寫很多的代碼,但是現(xiàn)在我們有了Async 和 await關(guān)鍵字,那么我們將通過書寫很少的并且簡潔的代碼來解決這個問題。

此外,我們還將看到更多的示例,如果任何第三個方法(如Method 3)都依賴于Method 1,那么它將在Wait關(guān)鍵字的幫助下等待Method 1的完成。

Async 和 await是代碼標記,它標記代碼位置為任務(wù)完成后控件應(yīng)該恢復的位置。

下面讓我們舉幾個例子來更好進行理解吧

C#中Async 和 await關(guān)鍵字的示例

我們將采用控制臺應(yīng)用程序進行演示。

第一個例子

在這個例子中,我們將采取兩個不相互依賴的方法。

class Program
{ 
  static void Main(string[] args)
  { 
Method1();
Method2();
Console.ReadKey();
  } 
 
  public static async Task Method1()
  { 
await Task.Run(() =>
    { 
      for (int i = 0; i < 100; i++)
      { 
Console.WriteLine(" Method 1"); 
      } 
    }); 
  } 
 
 
  public static void Method2()
  { 
    for (int i = 0; i < 25; i++)
    { 
Console.WriteLine(" Method 2"); 
    } 
  } 
} 

在上面給出的代碼中,Method 1和Method 2不相互依賴,我們是從主方法調(diào)用的。

在這里,我們可以清楚地看到,方法1和方法2并不是在等待對方完成。

輸出

現(xiàn)在來看第二個例子,假設(shè)我們有Method 3,它依賴于Method 1

第二個例子

在本例中,Method 1將總長度作為整數(shù)值返回,我們在Method 3中以長度的形式傳遞一個參數(shù),它來自Method 1。

在這里,在傳遞Method 3中的參數(shù)之前,我們必須使用AWAIT關(guān)鍵字,為此,我們必須使用調(diào)用方法中的async 關(guān)鍵字。

在控制臺應(yīng)用程序的Main方法中,因為不能使用async關(guān)鍵字而不能使用await 關(guān)鍵字,因為它會給出下面給出的錯誤。(但是如果你使用的是C#7.1及以上的方法是不會有問題的,因為C#7.1及以上的語法支持Mian方法前加async)

 

我們將創(chuàng)建一個新的方法,作為CallMethod,在這個方法中,我們將調(diào)用我們的所有方法,分別為Method 1、Method 2和Method 3。

class Program
{ 
  static void Main(string[] args)
  { 
callMethod();
Console.ReadKey();
  } 
 
  public static async void callMethod()
  { 
Task<int> task = Method1();
Method2();
    int count = await task;
Method3(count);
  } 
 
  public static async Task<int> Method1()
  { 
    int count = 0;
await Task.Run(() =>
    { 
      for (int i = 0; i < 100; i++)
      { 
Console.WriteLine(" Method 1"); 
count += 1;
      } 
    }); 
    return count;
  } 
 
  public static void Method2()
  { 
    for (int i = 0; i < 25; i++)
    { 
Console.WriteLine(" Method 2"); 
    } 
  } 
 
  public static void Method3(int count)
  { 
Console.WriteLine("Total count is " + count);
  } 
} 

在上面給出的代碼中,Method 3需要一個參數(shù),即Method 1的返回類型。在這里,await關(guān)鍵字對于等待Method 1任務(wù)的完成起著至關(guān)重要的作用。

輸出

第三個例子

.NET Framework4.5中有一些支持API,Windows運行時包含支持異步編程的方法。

在Async 和 await關(guān)鍵字的幫助下,我們可以在實時項目中使用所有這些,以便更快地執(zhí)行任務(wù)。

包含異步方法的API有HttpClient, SyndicationClient, StorageFile, StreamWriter, StreamReader, XmlReader, MediaCapture, BitmapEncoder, BitmapDecoder 等。

在本例中,我們將異步讀取大型文本文件中的所有字符,并獲取所有字符的總長度。

class Program
{ 
  static void Main()
  { 
Task task = new Task(CallMethod);
task.Start();
task.Wait();
Console.ReadLine();
  } 
 
  static async void CallMethod()
  { 
    string filePath = "E:\\sampleFile.txt"; 
Task<int> task = ReadFile(filePath);
 
Console.WriteLine(" Other Work 1"); 
Console.WriteLine(" Other Work 2"); 
Console.WriteLine(" Other Work 3"); 
 
    int length = await task;
Console.WriteLine(" Total length: " + length);
 
Console.WriteLine(" After work 1"); 
Console.WriteLine(" After work 2"); 
  } 
 
  static async Task<int> ReadFile(string file)
  { 
    int length = 0;
 
Console.WriteLine(" File reading is stating"); 
    using (StreamReader reader = new StreamReader(file))
    { 
      // Reads all characters from the current position to the end of the stream asynchronously  
      // and returns them as one string.  
      string s = await reader.ReadToEndAsync();
 
length = s.Length;
    } 
Console.WriteLine(" File reading is completed"); 
    return length;
  } 
} 

在上面給出的代碼中,我們調(diào)用ReadFile方法來讀取文本文件的內(nèi)容,并獲取文本文件中總字符的長度。

在sampleText.txt中,文件包含了太多的字符,因此讀取所有字符需要很長時間。

在這里,我們使用異步編程從文件中讀取所有內(nèi)容,所以它不會等待從這個方法獲得一個返回值并執(zhí)行其他代碼行,但是它必須等待下面給出的代碼行,因為我們使用的是等待關(guān)鍵字,我們將對下面給出的代碼行使用返回值。

int length = await task;
Console.WriteLine(" Total length: " + length); 

隨后,將按順序執(zhí)行其他代碼行。

Console.WriteLine(" After work 1"); 
Console.WriteLine(" After work 2"); 

輸出

最后

在這里,我們必須了解非常重要的一點,如果我們沒有使用await 關(guān)鍵字,那么該方法就作為一個同步方法。編譯器將向我們顯示警告,但不會顯示任何錯誤。

像上面這種簡單的方式一樣,我們可以在C#代碼中使用async 和await關(guān)鍵字來愉快的進行異步編程了。

最后的最后感謝大家的閱讀!希望對大家的學習有所幫助,也希望大家多多支持我們。

上一篇:C#開發(fā)windows服務(wù)實現(xiàn)自動從FTP服務(wù)器下載文件

欄    目:C#教程

下一篇:使用C# CefSharp Python采集某網(wǎng)站簡歷并且自動發(fā)送邀請短信的方法

本文標題:淺談C#中的Async和Await的用法詳解

本文地址:http://www.jygsgssxh.com/a1/C_jiaocheng/4825.html

網(wǎng)頁制作CMS教程網(wǎng)絡(luò)編程軟件編程腳本語言數(shù)據(jù)庫服務(wù)器

如果侵犯了您的權(quán)利,請與我們聯(lián)系,我們將在24小時內(nèi)進行處理、任何非本站因素導致的法律后果,本站均不負任何責任。

聯(lián)系QQ:835971066 | 郵箱:835971066#qq.com(#換成@)

Copyright © 2002-2020 腳本教程網(wǎng) 版權(quán)所有