小編這次要給大家分享的是C#異步編程應該注意什么,文章內容豐富,感興趣的小伙伴可以來了解一下,希望大家閱讀完這篇文章之后能夠有所收獲。
專注于為中小企業提供網站設計制作、成都做網站服務,電腦端+手機端+微信端的三站合一,更高效的管理,為中小企業撫順免費做網站提供優質的服務。我們立足成都,凝聚了一批互聯網行業人才,有力地推動了上1000+企業的穩健成長,幫助中小企業通過網站建設實現規模擴充和轉變。盡量不要編寫返回值類型為void的異步方法
在通常情況下,建議大家不要編寫那種返回值類型為void的異步方法,因為這樣做會破壞該方法的啟動者與方法本身之間的約定,這套約定本來可以確保主調方能夠捕獲到異步方法所發生的異常。
正常的異步方法是通過它返回的Task對象來匯報異常的。如果執行過程中發生了異常,那么Task對象就進入了faulted(故障)狀態。主調方在對異步方法所返回的Task對象做await操作時,該對象若已處在faulted狀態,系統則會將執行異步方法的過程中所發生的異常拋出,反之,若Task尚未執行到拋出異常的那個地方,則主調方的執行進度會暫停在await語句這里,等系統稍后安排某個線程繼續執行該語句下方的那些代碼時,異常才會拋出。
總結一句話就是:void的異步方法發生異常時,開發者得不到任何通知,程序既不會觸發普通的異常處理程序,也不會把這些異常記錄下來。總之,這會讓相關的線程默默的終止掉。
不要把同步方法與異步方法組合起來使用
用async關鍵字來修飾的方法意味著該方法有可能會在執行完所有工作之前就把控制權返回給主調方,而且,它返回給主調方的是個代表工作進度的Task對象。主調方可以查詢此對象的狀態,以了解該工作是否已經完成、尚未完成還是在執行過程中發生了故障。此外,這種方法還在暗示主調方:本方法所執行的工作可能要花費很長時間,因此建議你先去做其他一些事情,稍后再來向我索要結果。
與此相反,如果把某個方法設計成同步方法,那么意味著當該方法執行完畢時,它的后置條件必定能夠得到滿足。無論這個方法要花多長時間去完成工作,它都會采用與主調方相同的資源來完成,主調方必須等這個方法徹底執行完畢才能向下執行。
這兩種方法單獨寫起來都很清晰,但是如果把他們組合在一起就會讓方法變得十分難用,而且有可能導致各種bug,如死鎖。因此,這里提出兩條重要的原則。第一,不要讓同步方法必須等待異步方法執行完畢才能往下執行(盡量不用Wait()以及.result這些阻塞式的方法)。第二,不要讓異步方法把雖然耗時很長、計算量很大但是完全可以由自己執行的工作轉交給另一個異步任務去做。'
當然對于第二點,這并不是說計算量較大的任務絕對不能放在單獨的線程中執行,而是說不應該把只用一個線程就能迅速做好的任務刻意的拆解成許多個較小的部分,并把他們分別放在多個新的線程上執行,而是應該把整個任務都交給某個線程來執行才對。
使用異步方法時應盡量避免線程分配
異步任務看上去好像很神奇,因為這種任務刻意轉移到另一個地方去做,使得開啟這項任務的異步方法可以在該任務完成之后,從早前暫停的地方繼續往下推進。不過,要想發揮異步任務的功效,就必須保證把這項任務交出去確實能夠少占用一些資源,而不是僅僅會在相似的資源之間進行上下文切換。
如:對于一個控制臺程序,如果只是執行一項計算量較大且耗時較長的任務(或者說,運行時間較長的CPU密集型的任務),那么把該任務單獨放在另一個線程中并沒有多大好處。因為這樣做只能讓工作線程始終處于繁忙狀態,而主線程則必須一直卡在那里等待工作線程把任務做完。在這種情況下,實際上是用兩個線程來完成原本只需要一個線程就能做好的工作,造成了資源的浪費。
避免不必要的上下文切換
目前C#代碼中使用async以及await實現的異步方法默認是把await之后的代碼放在早前捕獲的那個上下文中執行的,這是因為這樣做比較穩妥,它最多只會引發幾次無謂的上下文切換,而不會使程序出現重大的錯誤,與之相反,如果系統不把山下文切換回去,那么萬一遇到的是只能在特定的上下文中才能執行的代碼,那么程序就有可能崩潰。因此,無論有沒有必要切換上下文,系統都會切換至早前捕獲到的那個上下文,并把await之后的語句放在那個上下文執行。
如果不想讓系統做出這樣的安排,那么可以調用ConfigureAwait()方法。這表示接下來的那些代碼無須放在早前捕獲的上下文中執行。例如在很多程序集中,await語句之后的那些代碼一般都與上下文無關,因此與,可以調用Task對象的ConfigureAwait()方法告訴系統,在執行完這項任務之后,不必專門把await下面的代碼放在早前捕獲的上下文中運行。如下所示:
public static async Task<XElement> ReadPacket(string url) { var result=await DownloadAsync(url) .ConfigureAwait(false); return XElement.Parse(result); }
另外有需要云服務器可以了解下創新互聯scvps.cn,海內外云服務器15元起步,三天無理由+7*72小時售后在線,公司持有idc許可證,提供“云服務器、裸金屬服務器、高防服務器、香港服務器、美國服務器、虛擬主機、免備案服務器”等云主機租用服務以及企業上云的綜合解決方案,具有“安全穩定、簡單易用、服務可用性高、性價比高”等特點與優勢,專為企業上云打造定制,能夠滿足用戶豐富、多元化的應用場景需求。
分享文章:C#異步編程應該注意什么-創新互聯
網頁URL:http://vcdvsql.cn/article14/dgoige.html
成都網站建設公司_創新互聯,為您提供標簽優化、全網營銷推廣、自適應網站、微信公眾號、企業網站制作、小程序開發
聲明:本網站發布的內容(圖片、視頻和文字)以用戶投稿、用戶轉載內容為主,如果涉及侵權請盡快告知,我們將會在第一時間刪除。文章觀點不代表本網站立場,如需處理請聯系客服。電話:028-86922220;郵箱:631063699@qq.com。內容未經允許不得轉載,或轉載時需注明來源: 創新互聯