簡體   English   中英

如何更改異步方法調用以防止強制異步調用堆棧

[英]How to change async method call to prevent forcing async up the call stack

如果我需要調用一個方法,在內部調用一些異步方法,作為一個fire and forget操作,我怎么能阻止這個調用強制“async”需要用完調用棧來說... MVC控制器?

例如:我的MVC控制器(非異步)調用業務層方法,該方法又調用Windows Azure Service Bus QueueClient.SendAsync(BrokeredMessage),將消息放入隊列中,但不需要等待它完成。

通常,在調用此控制器操作時,編譯器將拋出一個錯誤,指出此時無法啟動異步操作。

我知道不是等待或只是調用SendAsync()方法,我可以使用ContinueWith()跟進它,以便在異步操作的回調上執行代碼,但我被告知這不是一個正確的解決方案。 (請參閱對控制器中調用異步方法的響應)

有人會關心如何解決這種情況的最佳方法嗎? 並告訴我為什么ContinueWith()方法不正確?

MVC控制器方法處理HTTP請求並將相應的HTTP響應發送回客戶端。 如果我正確地理解了您的問題,您希望從異步MVC控制器方法中調用fire-and-forget方法,然后繼續執行HTTP響應傳遞,因此即發即棄方法不會保留響應。

實際上,您不能通過這種方式使用控制器方法來解決它,而無需等待其結果。 即,您可以,但是如果您的ASP.NET應用程序將重新啟動,或者IIS服務器從服務器場中取出,則永遠不會調用您的ContinueWith回調。 因此,您不知道該請求是否曾到達Windows Azure服務。

解決此問題的一種方法是在同一主機上或同一網絡上的另一台主機上運行輔助Web API或WCF服務(因此服務調用的轉換非常快)。 它可以是自托管服務。 您可以從MVC控制器調用此幫助程序服務,以便對即發即棄操作進行排隊 您將await此調用的結果,但在這種情況下它不是問題,因為此操作的調用方和被調用方都將存在於同一網絡上。

這樣,原始的MVC HTTP響應將不會被擱置。 在幫助程序服務中,您將await QueueClient.SendAsync()調用Windows Azure Bus並相應地處理此操作的結果。

調用Windows Azure Service Bus QueueClient.SendAsync(BrokeredMessage),將消息放入隊列中,但不需要等待它完成。

首先,我重新考慮這個假設。 如果您想要一個完全可靠的系統,該操作應該等待將消息發送到總線。 請注意,這通常是一個快速操作(100毫秒)。

通常,在調用此控制器操作時,編譯器將拋出一個錯誤,指出此時無法啟動異步操作。

確保您沒有任何async void方法或EAP方法調用 如果Azure存儲庫導致該異常,我會非常驚訝。

有人會關心如何解決這種情況的最佳方法嗎? 並告訴我為什么ContinueWith()方法不正確?

最好的解決方案是擁抱async ContinueWith可以工作,但使用起來很危險(它有很多參數,其中一些參數有不安全的默認值); awaitContinueWith幾乎相同,但沒有危險的默認值。


但是,如果100ms確實無法忍受,並且您願意放棄可靠性(在這種情況下,這意味着您接受這樣的事實:即使操作成功完成,某些消息也可能無法發送到總線,因此客戶認為他們確實 ),然后你可以使用我博客中BackgroundTaskManager來減少丟失消息的可能性。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM