2015-04-03 44 views
16

我們在MVC 5.1.3應用程序中發生此錯誤的頻率非常高,當它發生時,用戶必須刷新頁面並且它消失了,所以它是一個間歇性問題。MVC Action Filters集合已被修改;枚舉操作可能不會執行

我們發現診斷很棘手,因爲它似乎發生在框架內部。任何想法在哪裏看?

這是完整的堆棧:

System.InvalidOperationException: Collection was modified; enumeration operation may not execute. 
    at System.Collections.Generic.List`1.Enumerator.MoveNextRare() 
    at System.Web.Mvc.FilterProviderCollection.GetFilters(ControllerContext controllerContext, ActionDescriptor actionDescriptor) 
    at System.Web.Mvc.ControllerActionInvoker.GetFilters(ControllerContext controllerContext, ActionDescriptor actionDescriptor) 
    at System.Web.Mvc.Async.AsyncControllerActionInvoker.BeginInvokeAction(ControllerContext controllerContext, String actionName, AsyncCallback callback, Object state) 
    at System.Web.Mvc.Async.AsyncControllerActionInvoker.BeginInvokeAction(ControllerContext controllerContext, String actionName, AsyncCallback callback, Object state) 
    at System.Web.Mvc.Controller.<BeginExecuteCore>b__1c(AsyncCallback asyncCallback, Object asyncState, ExecuteCoreState innerState) 
    at System.Web.Mvc.Async.AsyncResultWrapper.WrappedAsyncVoid`1.CallBeginDelegate(AsyncCallback callback, Object callbackState) 
    at System.Web.Mvc.Async.AsyncResultWrapper.WrappedAsyncResultBase`1.Begin(AsyncCallback callback, Object state, Int32 timeout) 
    at System.Web.Mvc.Async.AsyncResultWrapper.Begin[TState](AsyncCallback callback, Object callbackState, BeginInvokeDelegate`1 beginDelegate, EndInvokeVoidDelegate`1 endDelegate, TState invokeState, Object tag, Int32 timeout, SynchronizationContext callbackSyncContext) 
    at System.Web.Mvc.Controller.BeginExecuteCore(AsyncCallback callback, Object state) 
    at System.Web.Mvc.Async.AsyncResultWrapper.WrappedAsyncResultBase`1.Begin(AsyncCallback callback, Object state, Int32 timeout) 
    at System.Web.Mvc.Async.AsyncResultWrapper.Begin[TState](AsyncCallback callback, Object callbackState, BeginInvokeDelegate`1 beginDelegate, EndInvokeVoidDelegate`1 endDelegate, TState invokeState, Object tag, Int32 timeout, SynchronizationContext callbackSyncContext) 
    at System.Web.Mvc.Controller.BeginExecute(RequestContext requestContext, AsyncCallback callback, Object state) 
    at System.Web.Mvc.MvcHandler.<BeginProcessRequest>b__4(AsyncCallback asyncCallback, Object asyncState, ProcessRequestState innerState) 
    at System.Web.Mvc.Async.AsyncResultWrapper.WrappedAsyncVoid`1.CallBeginDelegate(AsyncCallback callback, Object callbackState) 
    at System.Web.Mvc.Async.AsyncResultWrapper.WrappedAsyncResultBase`1.Begin(AsyncCallback callback, Object state, Int32 timeout) 
    at System.Web.Mvc.Async.AsyncResultWrapper.Begin[TState](AsyncCallback callback, Object callbackState, BeginInvokeDelegate`1 beginDelegate, EndInvokeVoidDelegate`1 endDelegate, TState invokeState, Object tag, Int32 timeout, SynchronizationContext callbackSyncContext) 
    at System.Web.Mvc.MvcHandler.BeginProcessRequest(HttpContextBase httpContext, AsyncCallback callback, Object state) 
    at System.Web.HttpApplication.CallHandlerExecutionStep.System.Web.HttpApplication.IExecutionStep.Execute() 
    at System.Web.HttpApplication.CallHandlerExecutionStep.System.Web.HttpApplication.IExecutionStep.Execute() 
    at System.Web.HttpApplication.ExecuteStep(IExecutionStep step, Boolean& completedSynchronously) 

已經有過類似的問題之前問:Collection was modified; enumeration operation may not execute,但這被升級到MVC 5,我們已經在5

+0

在其代碼你得到這個? – Mairaj 2015-04-15 04:26:01

+4

顯然有些東西是在運行時從全局過濾器集合中添加或刪除過濾器。這是應該只在啓動時發生的事情,所以你應該做的第一件事就是搜索全局過濾器被修改的任何地方,並且在任何它沒有被啓動的地方完成它是可疑的。 – 2015-04-16 01:06:14

+0

您是否使用過其他工具來更好地瞭解發生了什麼?像[Elmah](https:// github。com/alexbeletsky/elmah-mvc)或[glimpse](http://getglimpse.com/) – 2015-04-17 12:08:46

回答

4

由於@Erik解決在評論中說,很明顯,在執行請求期間,正在修改的過濾器集合,在應用程序啓動期間它只應該被填充。

一種可能性是您註冊了一個正在破壞代碼的自定義IFilterProvider。下面是從發生錯誤的源代碼(由FilterProviderCollection

 for (int i = 0; i < providers.Length; i++) 
     { 
      IFilterProvider provider = providers[i]; 
      foreach (Filter filter in provider.GetFilters(controllerContext, actionDescriptor)) 
      { 
       filters.Add(filter); 
      } 
     } 

provider.GetFilter(...)返回一個List其在FilterProviderCollectionforeach塊枚舉期間以後修改。

這裏就是我腦海爲你測試:

所有的
  • 首先,確保你沒有註冊自定義IFilterProvider(無論是你,還是你可能會使用一個庫)。如果是這樣,那是主要的嫌疑人。

  • 請在代碼中查找GlobalFilterCollectionGlobalFilters類的所有用法。對Global Collection的任何修改只能從Global.asax中的Application_StartStartup類(如果您使用的是OWIN)進行修改

  • 查找創建過濾器或訪問它們的線索。

  • 嘗試升級到MVC 5.2。如果這是框架問題(這似乎不太可能),這可能會解決它。 (我正在使用5.2.2.0,並且在開發或生產中沒有看到任何類似的問題)

  • 調試您的應用程序,並在Application_BeginRequest的開始處和控制器操作中設置斷點。嘗試檢查全局過濾器集合,看看是否有任何變化。

  • 也許註冊自定義IFilterProvider和檢查通過調試或記錄的行爲能有所幫助。

相關問題