2015-09-25 49 views
6

可以說你有一個服務API調用。被調用者在某種程度上性能至關重要,因此爲了不超過必要的API調用時間,使用了一種SaveAsync()方法。然而,我不能await它,因爲這會阻止API調用的時間與非異步版本一樣長(或者甚至更長)。您是否需要等待異步方法?

我問原因是這樣的:如果你await電話,有沒有Task對象返回被垃圾回收的機會嗎?如果是這樣,那會中斷正在運行的任務嗎?

+0

你能表現出位的代碼,其中你會等待這種方法? –

+1

你確定等待會持有API嗎?據我所知,等待點將被存儲在空間塊,當結果會來CLR將處理您的代碼 –

回答

6

我問的原因是這樣的:如果你不等待這個調用,那麼Task對象返回的機會是否會被垃圾回收?

一般情況下,不應該發生。對任務進行排隊的底層TaskScheduler通常會在所需的生命週期內保持對其的引用,直到完成爲止。你可以看到,TaskScheduler.QueueTask文檔中:

典型的實現將任務存儲在內部數據結構,這將讓將在未來一段時間內執行這些任務的線程提供服務。

你真正的問題是將與ASP.NET SynchronizationContext一起使用,它跟蹤運行時正在進行的異步操作。如果您的控制器操作在異步操作之前完成,您將會遇到異常。

如果你想擁有「射後不理」在ASP.NET操作,你應該確保與ASP.NET運行時註冊它們,或者通過HostingEnvironment.QueueBackgroundWorkItemBackgroundTaskManager

+0

的一部分幸運的是,這是託管在Windows服務,而不是在asp.net。但對於任何想在asp.net中這樣做的人來說,這都是很好的信息。 – Alex

2

不,它不會中斷正在運行的任務,但是您也不會觀察任務中的異常,這並不是很好。您可以(至少部分)避免將所有正在運行的代碼包裝在try ... catch中並記錄異常。另外,如果你在asp.net裏面,那麼你的整個應用程序可能會被停止或回收,並且在這個的情況下你的任務會被中斷。這很難避免 - 您可以註冊AppPool關閉通知,或者使用類似Hangfire的東西。