在使用async
和await
時,有時我會覺得使用它很麻煩,因為我覺得它毫無意義。我沒有成功地證明這一點(不可否認,保持這種狀態并不會影響性能)。在下面的示例中,我如何驗證(或拒絕)我的聲明。
bool empty = await Context.Stuff.AnyAsync();
if(empty)
throw new Exception();
我的主張是,由于我們立即使用檢查結果來驗證是否應該離開該方法,因此需要同步啟動該調用。因此,我相信下面的性能不會更差。
bool empty = Context.Stuff.Any();
if(empty)
throw new Exception();
我如何驗證我的主張(經驗除外)?
我同意所有評論;這不是關于你對結果做什么以及什么時候做,而是關于在異步操作運行時,執行你的代碼的thread被允許去做什么。如果這個東西是數據庫中一個復雜的視圖,基于一個需要5分鐘才能運行的查詢,那么任何東西都會阻塞你的thread5分鐘。AnyAsync可以讓thread在這段時間內為您的Web服務器提供數以萬計的請求。如果您阻止了一個thread,那么Web服務器將不得不啟動另一個來為其他人服務,threads很昂貴。
Async不是“更好的性能”,意思是“使其異步并運行更快”——代碼以相同的速度執行。Async是關于“更好地使用資源”-您需要更少的threads,他們更忙/更少無所事事地等待IO完成
如果它是一間辦公室,那就好比你在等電話的時候煮咖啡;想象一下,你接到煤氣公司的電話,老板大喊著要喝杯咖啡。如果你是異步的,你會把它放在揚聲器上,在等待的時候站起來煮咖啡,等待等待等待音樂停止的聲音和煤氣公司說“你好”的聲音。如果你是同步的,你會坐在那里無視老板的要求,而其他人在煮咖啡(這意味著老板必須雇用其他人)。讓你坐在那里無所事事,只是等待,并且不得不雇用其他人,比讓你在x工作到一定程度后再去做其他事情要昂貴得多。如果你是異步的,你會在等待水壺沸騰的時候去重新裝滿打印機。如果你正在等待同步,而初級辦公室人員正在等待水壺燒開,老板將不得不雇傭另一個人來填充打印機。。
當煤氣公司最終讓你休息時,是你還是其他人接聽電話取決于你是否煮好了咖啡,是否有空,和/或你是否已配置等待,以表明必須由你接聽電話(真),或辦公室中是否有人可以繼續(假)
這取決于你對結果還將做些什么。如果您需要反復詢問結果的長度并隨機訪問它,那么請使用
ToArrayAsync
將其轉換為數組,然后將其作為本地緩存數據進行所有操作。除非結果是一個兩TB大的查詢😀如果您實際上只需要一次計數,那么將所有內存用于分配數組并獲取其長度是沒有意義的;只要做
CountAsync
這兩個問題似乎都與“異步還是否”的問題不完全相關如果你的IEnumerable是通過一個緩慢的網絡進行的,并且是一個巨大而緩慢的查詢,那么它仍然會返回到“讓thread關閉,然后忙于做其他事情,這樣你就不必再啟動threads”。請注意,這里的“慢”甚至可能意味著幾十毫秒。我們不必討論分鐘操作,就可以看到異步的好處
非常快的操作當然,您可以進行同步,以節省設置狀態機的微小成本,但要確定設置狀態機的成本與使thread可以做其他事情的成本之間的臨界點,而不是讓它等待一段時間;這臺機器價格很低。面對這種選擇,如果可用的話,我通常會選擇異步,尤其是在涉及任何IO的情況下
每種情況下,你都必須賽馬;op完成同步的速度有多快,執行異步狀態管理需要多長時間。對于整個代碼庫來說,這樣做可能會很令人厭煩,這就是為什么我傾向于繼續“如果異步可用,并且不僅僅是為了異步,那么可能有人認為使用異步是明智的,所以我們應該使用它”。如果您使用它在庫中的存在作為一個指示器,表明您應該在代碼中利用它(然后向代碼用戶指示他們should..),那么異步一直傳播到代碼庫中可能是一件好事