2015-04-03 112 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和检查通过调试或记录的行为能有所帮助。

相关问题