c#5.0推出了新語法,await與async,但相信大家還是很少使用它們。關於await與async有很多文章講解,但有沒有這樣一種感覺,你看完後,總感覺這東西很不錯,但用的時候,總是想不起來,或者不知道該怎麼用。
為什麼呢?我覺得大家的await與async的開啟方式不正確。
正確的開啟方式
首先看下使用約束。
1、await 只能在標記了async的函式內使用。
2、await 等待的函式必須標記async。
有沒有感覺這是個迴圈?沒錯,這就是個迴圈。這也就是為什麼大家不怎麼用他們的原因。這個迴圈很討厭,那麼怎麼破除這個迴圈呢?
【很簡單,await等待的是執行緒,不是函式。】
不理解嗎?沒關係,接著看下去。
下面從頭來講解,首先看這麼一組對比
async task等於intpublic static int noasynctest()
public static async taskasynctest()
這意味著我們在正常呼叫這兩個函式時,他們是等效的。那麼用async task來修飾int目的是什麼呢?
目的是為了讓這個方法這樣被呼叫 await asynctest(),但直接這樣呼叫,並不會開啟執行緒,那這樣費勁的修飾是不是就沒什麼意義了呢。
當然不是,那什麼時候會讓 await asynctest()有意義呢?
我們接著往下看,修改asynctest如下。然後,此時再呼叫await asynctest(),你會神奇的發現,依然沒有卵用。。。
excute方法正常執行,而asynctest內執行的執行緒,自己執行自己的。
這個邏輯是這樣的,如果想要獲取執行緒返回結果,就自然要等待執行緒結束。public static async void excute()
public static async taskasynctest()
); return 1;
}
執行一下,我們將看下面的結果。
但是,好像await asynctest();還是沒啟作用。沒錯,事實就是,他真的不會起作用。。。public static async taskasynctest()
).getawaiter().getresult();
return 1;
}
那麼怎麼才能讓他起作用呢?
首先,我們定義乙個普通函式,他的返回值是乙個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之後,就會開啟...