我們有一個ASP.NET MVC網站,並將所有文本存儲在MongoDB中。 LocalizationTextManager類負責提供這些文本並在內部緩存它們。通常,這種方法非常快(< 5ms),如果結果存在於緩存中,則速度更快。MongoDB 2.0驅動程序和非異步代碼的潛在死鎖
我們有兩個方法:GetString和GetStringAsync。 GetStringAsync是首選,但我們在Razor中使用GetString方法,或者在某些不屬於異步上下文的罕見情況下使用。
MongoDB有一個異步驅動程序,我需要非同步實現它。因此我們嘗試了幾種方法。我確保我在代碼中的任何位置都設置了ConfigureAwait(false)。
FindOrAddTextFromRepositoryAsync(key).Result;
Task.Run(async() => await FindOrAddTextFromRepositoryAsync(key)).Result;
Task.Run(async() => await FindOrAddTextFromRepositoryAsync(key).ConfigureAwait(false)).Result;
我知道我不需要任務內的ConfigureAwait(false)(因爲應該沒有同步上下文)。
我剛剛部署了該網站,並在部署後掛起。該過程重新啓動後,它正在工作。我之前做過轉儲,並發現有很多這些方法調用:
w3wp(4).DMP中的以下線程正在等待System.Threading.Monitor.Wait。 〜100 Thread threaded:
mscorlib_ni!System.Threading.ManualResetEventSlim.Wait(Int32, System.Threading.CancellationToken)+3ec
mscorlib_ni!System.Threading.Tasks.Task.SpinThenBlockingWait(Int32, System.Threading.CancellationToken)+db
mscorlib_ni!System.Threading.Tasks.Task.InternalWait(Int32, System.Threading.CancellationToken)+24a
mscorlib_ni!System.Threading.Tasks.Task`1[[System.__Canon, mscorlib]].GetResultCore(Boolean)+36
GP.Components.Globalization.LocalizationTextManager.GetString(System.String, System.String)+2f4
GP.Components.Globalization.LocalizationTextManager.GetString(System.String, System.Globalization.CultureInfo)+8a
我的問題是:我如何正確實現它?另一個想法是使用LimitedThreadsScheduler
來確保它不會嚴重並行化。
我知道,這正是我所做的;) – SebastianStehle
更新了一些想法的答案 – VMAtm
@VMAtm只是要清楚,你會推薦什麼?使用委託來分配值,然後使用Task.Wait Any? –