我們最近開發了一個新的ASP.NET MVC 4 web應用程序(C#/ Visual Studio)。經過本地測試和調試後,我們將其部署到生產環境中,然後開始獲得越來越多的健康監測郵件。這些具有不同的異常消息:關於併發使用MVC應用程序的堆棧空問題
- 堆棧爲空。
- 收藏已修改;枚舉操作可能不會執行。
- 項目已被添加。鍵入詞典:添加'ALL_HTTP'鍵:'ALL_HTTP'(其他鍵也提到)。
- 價值不符合預期範圍。
例如,我們無法簡單地解決或重現一系列錯誤類型。 「空棧」是最常發生的一次,每天發生幾次100次(例如1-10%的用戶),因此我們將重點放在這一次,因爲其他錯誤似乎相關。這是一個部分堆棧跟蹤:
Exception information:
Exception type: System.InvalidOperationException
Exception message: Stack empty.
...
Stack trace: at System.ThrowHelper.ThrowInvalidOperationException(ExceptionResource resource)
at System.Collections.Generic.Stack`1.Pop()
at System.Web.WebPages.TemplateStack.Pop(HttpContextBase httpContext)
如圖所示堆棧跟蹤大多完全位於MVC框架(System.Web)中。我們自己的代碼中唯一出現在某些堆棧跟蹤中的代碼位於請求的URL的視圖(.cshtml文件)中,然後在@ Html.RenderAction()調用中。到目前爲止,我們已經將很多這些重構到RenderPartial()調用中。這會導致堆棧跟蹤中看不到更多視圖,儘管某些RenderPartial現在也提供了一些
搜索此錯誤指示併發/並行執行是原因。這與我們最初無法在本地重現錯誤的事實相符,但它確實發生在生產上。我們沒有進行負載測試,但現在已經能夠通過同時啓動大量應用程序/請求,在本地開發者系統上重現錯誤。然而,在我們的代碼中,沒有任何操作是通過顯式並行指令完成的
這似乎與MVC視圖的線程安全無關。但很難想象沒有其他人會遇到這種情況。我們每天有幾千名訪問者,在任何時候大約有30多名活躍用戶。可悲的是,這個數字正在下降,因爲谷歌排名下降(與這個問題有關)。
有沒有人知道這個問題的解決方案?
你是否將模型中的任何可能被多線程訪問的對象作爲模型傳遞?就像一個共享對象? – vtortola
vtorola不是真的! Wel所有模型都從具有靜態數據庫上下文對象的BaseModel進行擴展,但是這存儲在HTTPContext(使用鍵)中。這樣做是爲了在'每個請求'的基礎上使用它(它在第一次訪問時被延遲加載)。 堆棧跟蹤不指向此代碼,它們只在視圖邏輯中。此外,我以前已經在代碼中添加了一個'鎖'語句,以便以防萬一。這似乎沒有改變任何東西。 我們正在使用實體框架。 – Bart
令人毛骨悚然的Woa:D您應該使用您的DbContext作爲控制器的一部分,從數據庫生成所需的POCO對象,然後創建視圖模型。一個視圖應該是線程安全的,我從來沒有見過這樣的錯誤,所以我建議開始深入地看看令人毛骨悚然的共享DbContext。也許堆棧跟蹤並不指向那個BaseModel對象,但絕對是它的一部分被多個線程共享。 – vtortola