C 中的Async 和 Await 的用法詳解

2022-01-12 21:26:39 字數 3502 閱讀 4669

自從c# 5.0時代引入async和await關鍵字後,非同步程式設計就變得流行起來。尤其在現在的.net core時代,如果你的**中沒有出現async或者await關鍵字,都會讓人感覺到很奇怪。

想象一下當我們在處理ui和按鈕單擊時,我們需要執行乙個長時間執行的方法,比如讀取乙個大檔案或其他需要很長時間的任務,在這種情況下,整個應用程式必須等待這個長時間執行的任務完成才算完成整個任務。

換句話說,如果同步應用程式中的任何程序被阻塞,則整個應用程式將被阻塞,我們的應用程式將停止響應,直到整個任務完成。

在這種情況下,非同步程式設計將非常有用。通過使用非同步程式設計,應用程式可以繼續進行不依賴於整個任務完成的其他工作。

在async 和 await關鍵字的幫助下,使得非同步程式設計變得很簡單,而且我們將獲得傳統非同步程式設計的所有好處。

假設我們分別使用了兩種方法,即method 1和method 2,這兩種方法不相互依賴,而method 1需要很長時間才能完成它的任務。在同步程式設計中,它將執行第乙個method 1,並等待該方法的完成,然後執行method 2。因此,這將是乙個時間密集型的過程,即使這兩種方法並不相互依賴。

我們可以使用簡單的多執行緒程式設計並行執行所有方法,但是它會阻塞ui並等待完成所有任務。要解決這個問題,我們必須在傳統程式設計中編寫很多的**,但是現在我們有了async 和 await關鍵字,那麼我們將通過書寫很少的並且簡潔的**來解決這個問題。

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

async 和 await是**標記,它標記**位置為任務完成後控制項應該恢復的位置。

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

c#中async 和 await關鍵字的示例

我們將採用控制台應用程式進行演示。

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

class program

public static async task method1()

});

} public static void method2()

} }

在上面給出的**中,method 1和method 2不相互依賴,我們是從主方法呼叫的。

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

輸出

現在來看第二個例子,假設我們有method 3,它依賴於method 1

在本例中,method 1將總長度作為整數值返回,我們在method 3中以長度的形式傳遞乙個引數,它來自method 1。

在這裡,在傳遞method 3中的引數之前,我們必須使用await關鍵字,為此,我們必須使用呼叫方法中的async 關鍵字。

在控制台應用程式的main方法中,因為不能使用async關鍵字而不能使用await 關鍵字,因為它會給出下面給出的錯誤。(但是如果你使用的是c#7.1及以上的方法是不會有問題的,因為c#7.1及以上的語法支援mian方法前加async)

我們將建立乙個新的方法,作為callmethod,在這個方法中,我們將呼叫我們的所有方法,分別為method 1、method 2和method 3。

class program

public static async void callmethod()

public static async taskmethod1()

});

return count;

} public static void method2()

} public static void method3(int count)

}

在上面給出的**中,method 3需要乙個引數,即method 1的返回型別。在這裡,await關鍵字對於等待method 1任務的完成起著至關重要的作用。

輸出

.net framework4.5中有一些支援api,windows執行時包含支援非同步程式設計的方法。

在async 和 await關鍵字的幫助下,我們可以在實時專案中使用所有這些,以便更快地執行任務。

包含非同步方法的api有httpclient, syndicationclient, storagefile, streamwriter, streamreader, xmlreader, mediacapture, bitmapencoder, bitmapdecoder 等。

在本例中,我們將非同步讀取大型文字檔案中的所有字元,並獲取所有字元的總長度。

class program

static async void callmethod()

static async taskreadfile(string file)

console.writeline(" file reading is completed");

return length;

} }

在上面給出的**中,我們呼叫readfile方法來讀取文字檔案的內容,並獲取文字檔案中總字元的長度。

在sampletext.txt中,檔案包含了太多的字元,因此讀取所有字元需要很長時間。

在這裡,我們使用非同步程式設計從檔案中讀取所有內容,所以它不會等待從這個方法獲得乙個返回值並執行其他**行,但是它必須等待下面給出的**行,因為我們使用的是等待關鍵字,我們將對下面給出的**行使用返回值。

int length = await task;

console.writeline(" total length: " + length);

隨後,將按順序執行其他**行。

console.writeline(" after work 1");  

console.writeline(" after work 2");

輸出

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

像上面這種簡單的方式一樣,我們可以在c#**中使用async 和await關鍵字來愉快的進行非同步程式設計了。

最後的最後感謝大家的閱讀!

本文大部分內容翻譯自:

C 中 async 和 await 的基本使用

經常在 c 的 中看到以async結尾的方法,大概知道意為非同步方法,但不知道怎麼使用,也不知道如何定義。對於 同步 非同步 阻塞 非阻塞 這幾個概念還是比較清楚的。同步是指等待方法的執行完成 非同步是指設定方法執行後繼續其它操作,通過 的方式對結果進行其它操作 阻塞是指執行到這一步就不往後了,直到...

async和await的講解

普通的函式宣告 async function a 複製 宣告乙個函式表示式 let a async function 複製 async形式的箭頭函式 let a async 複製 async與await例項應用,基礎 控制器呼叫與server中查詢資料 exports.getbloglist asy...

async和await的使用

async其實是es7的才有的,是非同步操作的進化,其實就是封裝乙個promise的物件返回 async function test console.log test promiseasync方法在普通的函式前加上 async 關鍵字即可。執行這個函式,發現並沒有返回1111,而是通過promise...