日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程语言 > asp.net >内容正文

asp.net

在.NET中执行Async/Await的两种错误方法

發布時間:2023/12/4 asp.net 36 豆豆
生活随笔 收集整理的這篇文章主要介紹了 在.NET中执行Async/Await的两种错误方法 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

微信公眾號:架構師高級俱樂部
關注可了解更多的編程,架構知識。問題或建議,請公眾號留言;
如果你覺得此文對你有幫助,歡迎轉發

在.NET中執行異步/等待的兩種錯誤方法

在應用開發中,我們為了提高應用程序的吞吐能力或者異步操作來減少耗時,通常會使用多線程來達到目的,而在C#語言中由于async/await必殺技的存在,大多會使用此來簡化多線程操作,async/await的具體使用方式想必大家已爛熟于心,不再贅述,今天主要談談在我們經常所謂的async/await操作真的是正確的嗎?你又真的用對他了嗎?

情景1:消除異步方法優勢

請看下面代碼示例

ServiceClient client = new ServiceClient(); ServiceRequest request = new ServiceRequest(); request.Id = newId; var responseTask = Task.Run(() => client.GetServicesAsync(request)); ServiceResponse response = await responseTask;

以上代碼片段在一個異步方法中,此方法在另一個Task中返回一個Task!(Task.Run) 這是多余的。如果該方法已經返回Task,則我們不應該將其包裝在另一個Task中。因此,在這種情況下,解決方案也非常簡單,取消一切不必要的Task:

ServiceClient client = new ServiceClient(); ServiceRequest request = new ServiceRequest(); request.Id = newId; var responseTask = client.GetServicesAsync(request); ServiceResponse response = await responseTask;

情景2:濫用Task.Run()

在工作中大多使用Task.Run的代碼給人的印象是異步有助于提高性能。這是正確的,但僅是非常片面的。Async/Await的目的是幫助提高吞吐量。改善性能僅僅是副作用。

因此在工作中會發現各種奇奇怪怪的代碼,例如以下為了配合外部異步方法,又由于內部各種原因沒有實現異步方法,不得不用Task.Run來包裹同步方法而達到語法要求。

MyService client = new MyService(); var responseTask = Task.Run(() => client.GetData(request)); var response = await responseTask;

換句話說:使用Task.Run()包裝了一個同步調用。

這里的問題是方法client.GetData()本身并不是異步方法,通過將異步包裝器置于同步方法之上,我們正在做一個稱為“async-over-sync異步超同步”的反模式,這在大多數情況下最終不是一個推薦的做法。不是因為它不起作用(而是起作用),而是因為它效率不高。

之所以如此,原因是很長的,而且涉及很多,如果感興趣可在文章末尾找到Stephen作者相關對此問題的詳細解釋地址[1]??偨Y一下,以上代碼非常糟糕,因為實現異步的好處是通過在線程不執行任何操作(例如,等待服務響應)時“釋放”線程來提高吞吐量。上面的示例確實釋放了一個線程,它也立即消耗了另一個線程來執行任務包裝的代碼,并且該消耗的線程在等待服務響應時被阻塞。因此,我們沒有提高吞吐量,只是將工作從一個線程轉移到了另一個線程。而且在并發下,以上使用方式在工作中也極大的降低了系統性能!


解決方案可以簡化為:不要對同步方法使用異步包裝器!只需同步調用它們即可。在這種情況下,理論上的性能優勢將被潛在的問題所抵消,這些潛在的問題在最壞的情況下可能包括死鎖。

過度使用Task.Run()有很大安全隱患,尤其在你未搞懂你寫了什么的時候,這種影響在復雜業務和超大并發下出問題非常難排查!在發現性能嚴重影響又找不到原因的時候,請排查出所有使用Task.Run的代碼,確定是否是以上兩種情況,解決他們可能就海闊天空了

摘要

在.NET或者.Netcore中使用Async/Await都是一項技巧,必須謹慎使用。在上面的示例中,開發團隊試圖使他們的應用程序性能更好,但最終由于對他們的代碼過度使用Async/Await而使情況變的難以控制。

總之應該記住兩件事:

不要將異步任務包裝在另一個異步包裝器Task.Run中。

不要在同步調用上使用異步包裝器。

有很多方法可以修正使用異步/等待的ASP.NET代碼。



更多請參考

[1]:https://devblogs.microsoft.com/pfxteam/should-i-expose-asynchronous-wrappers-for-synchronous-methods/(我應該為同步方法加異步包裝器Task.Run嗎)

總結

以上是生活随笔為你收集整理的在.NET中执行Async/Await的两种错误方法的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。