C 語法 await與async的正確開啟方式

2021-09-20 08:34:36 字數 2670 閱讀 3397

c#5.0推出了新語法,await與async,但相信大家還是很少使用它們。關於await與async有很多文章講解,但有沒有這樣一種感覺,你看完後,總感覺這東西很不錯,但用的時候,總是想不起來,或者不知道該怎麼用。

為什麼呢?我覺得大家的await與async的開啟方式不正確。

正確的開啟方式

首先看下使用約束。

1、await 只能在標記了async的函式內使用。

2、await 等待的函式必須標記async。

有沒有感覺這是個迴圈?沒錯,這就是個迴圈。這也就是為什麼大家不怎麼用他們的原因。這個迴圈很討厭,那麼怎麼破除這個迴圈呢?

【很簡單,await等待的是執行緒,不是函式。】

不理解嗎?沒關係,接著看下去。

下面從頭來講解,首先看這麼一組對比

public static int noasynctest()

public static async taskasynctest()

async task等於int

這意味著我們在正常呼叫這兩個函式時,他們是等效的。那麼用async task來修飾int目的是什麼呢?

目的是為了讓這個方法這樣被呼叫 await asynctest(),但直接這樣呼叫,並不會開啟執行緒,那這樣費勁的修飾是不是就沒什麼意義了呢。

當然不是,那什麼時候會讓 await asynctest()有意義呢?

我們接著往下看,修改asynctest如下。然後,此時再呼叫await asynctest(),你會神奇的發現,依然沒有卵用。。。

excute方法正常執行,而asynctest內執行的執行緒,自己執行自己的。

public static async void excute()

public static async taskasynctest()

); return 1;

}

這個邏輯是這樣的,如果想要獲取執行緒返回結果,就自然要等待執行緒結束。

執行一下,我們將看下面的結果。

public static async taskasynctest()

).getawaiter().getresult();

return 1;

}

但是,好像await asynctest();還是沒啟作用。沒錯,事實就是,他真的不會起作用。。。

那麼怎麼才能讓他起作用呢?

首先,我們定義乙個普通函式,他的返回值是乙個task,然後我們得到task後,執行它,再用await等待這個task。

於是我們就得到這樣的結果。

如圖,這樣寫await asynctest();就起作用了。

所以,還是那句話,await等待的是執行緒,不是函式。

但在圖里,我們發現很奇怪的一點,結束excute也是執行緒3,而不是執行緒1。也就是說,await會對執行緒進行優化。

下面看下兩組**的對比,讓我們就更清楚的了解下await。

第一組,使用await等待執行緒。

public static async void excute()

public static async task singleawait()

); await task.run(() =>

);console.writeline(thread.currentthread.gethashcode() + " awaittest結束 " + datetime.now);

第二組,使用等待執行緒結果,等待執行緒。

public static async void excute()

public static async task singlenoawait()

).getawaiter().getresult();

task.run(() =>

).getawaiter().getresult();

console.writeline(thread.currentthread.gethashcode() + " singlenoawait結束 " + datetime.now);

可以明確的看到,第二組,執行緒重新回到了主線程1中,而第一組,已經被優化到了執行緒4中。結語

await是一種很便捷的語法,他的確會讓**簡潔一些,但他主動優化執行緒的功能,如果不了解就使用,可能會導致一些奇怪的bug發生。

這也是官方為什麼只提供了await呼叫服務的例子,因為,在程式內呼叫,await還是要了解後,再使用,才安全。

C 非同步程式設計await與async

使用async修飾符可將方法 lambda 表示式或匿名方法指定為非同步。如果對方法或表示式使用此修飾符,則其稱為非同步方法 class program public async static task runtimeasync 在非同步函式中,await之後會自動建立出乙個執行緒。執行結果就可以看...

await與async簡單理解

使用 async 可以定義乙個 非同步函式 async 函式的實際返回值總是乙個 promise 物件 await的意思就是等待。它後面可以跟乙個表示式。如果是值 如字串 數字 普通物件等等 的話,返回值就是本身的值。await 操作符用於等待乙個 promise 物件,它只能在非同步函式 asyn...

C 正確理解 async 與 await

msdn文件裡提到的不會建立新執行緒是指async函式本身不會直接在新執行緒中執行。在 mvc 模式下 非同步action執行到await之前都是再loop執行緒,loop執行緒池的執行緒數是有限的,在iis執行緒池的高階設定 queue length 裡可以設定,一旦執行到await之後,就會開啟...