2010-04-07 24 views
5

Actualmente estoy luchando con este "Colección se modificó; la operación de enumeración no puede ejecutar" problema.NHibernate: la colección se modificó; la operación de enumeración no se puede ejecutar

He buscado sobre este mensaje de error, y todo está relacionado con la instrucción foreach. Tengo algunas declaraciones foreach, pero simplemente representan los datos. No utilicé eliminar o agregar dentro de la instrucción foreach.

NOTA:

  1. El error ocurre al azar (alrededor de 4-5 veces al día).
  2. La aplicación es el sitio web de MVC.
  3. Hay aproximadamente 5 usuarios que operan estas aplicaciones (alrededor de 150 pedidos por día). ¿Podría ser que otros usuarios modifiquen la colección y luego ocurra este error?
  4. He Log4net instalación y la configuración se puede encontrar here
  5. Asegúrese de que el controlador tiene un constructor público sin parámetros tengo constructor público sin parámetros en AdminProductController

¿Alguien sabe por qué esto sucede y ¿Cómo resolver este problema?

Un amigo (Oskar) mencionó que

"Teoría: Tal vez el problema es que su configuración y sesión de fábrica se inicia en la primera solicitud después del reinicio de la aplicación Si una segunda solicitud entra en acción. antes de que finalice la primera solicitud , tal vez también intente inicializar y luego desencadenando este problema de alguna manera ".

Muchas gracias.

Daoming

Aquí está el mensaje de error:

System.InvalidOperationException se modificó Colección; la operación de enumeración no se puede ejecutar. System.InvalidOperationException: Se produjo un error al intentar crear un controlador de tipo 'WebController.Controllers.Admin.AdminProductController'. Asegúrese de que el controlador tenga un constructor público sin parámetros. ---> System.Reflection.TargetInvocationException: Excepción ha sido lanzada por el objetivo de una invocación. ---> NHibernate.MappingException: no se pudo configurar el almacén de datos desde la secuencia de entrada DomainModel.Entities.Mappings.OrderProductVariant.hbm.xml ---> System.InvalidOperationException: se modificó la colección; la operación de enumeración no se puede ejecutar. en System.Collections.ArrayList.ArrayListEnumeratorSimple.MoveNext() en System.Xml.Schema.XmlSchemaSet.AddSchemaToSet (esquema XmlSchema) en System.Xml.Schema.XmlSchemaSet.Add (String targetNamespace, esquema XmlSchema) al Sistema .Xml.Schema.XmlSchemaSet.Add (Esquema XmlSchema) en NHibernate.Cfg.Configuration.LoadMappingDocument (XmlReader hbmReader, String name) en NHibernate.Cfg.Configuration.AddInputStream (Stream xmlInputStream, String name) --- Fin del registro de la pila de la excepción interna --- en NHibernate.Cfg.Configuration.LogAndThrow (Excepción de excepción) en NHibernate.Cfg.Configuration.AddInputStream (corriente xmlInputStream, String name) en NHibernate.Cfg.Configuration.AddResource (String path, el montaje de la Asamblea) en NHibernate.Cfg.Configuration.AddAssembly (montaje Asamblea) en DomainModel.RepositoryBase ..ctor() en WebController.Controllers._baseController..ctor() en WebController.Controllers.Admin.AdminProductController..ctor() en System.RuntimeType.CreateInstanceImpl (Boolean publicO ólo, skipVisibilityChecks booleanas, Boolean FillCache) --- Final de seguimiento de pila de excepción --- en System.RuntimeType.CreateInstanceImpl (Boolean publicOnly, skipVisibilityChecks booleanas, Boolean FillCache) en System.Activator.CreateInstance (tipo Type, Boolean no pública) en System.Web.Mvc.DefaultControllerFactory.GetControllerInstance (RequestContext RequestContext, Tipo controllerType) --- final de seguimiento de pila de excepción --- en System.Web.Mvc.DefaultControllerFactory.GetControllerInstance (RequestContext RequestContext, controllerType Tipo) en System.Web.Mvc.DefaultControllerFactory.CreateController (RequestContext requestContext, String controllerName) en System.Web.Mvc.MvcHandler.ProcessRequestInit (HttpContextBase httpContext, ICon) Troller & controlador, IControllerFactory & fábrica) en System.Web.Mvc.MvcHandler.BeginProcessRequest (HttpContextBase HttpContext, AsyncCallback devolución de llamada, el estado del objeto) en System.Web.HttpApplication.CallHandlerExecutionStep.System.Web.HttpApplication.IExecutionStep.Execute() en System.Web.HttpApplication.ExecuteStep (paso IExecutionStep, Boolean & completedSynchronously)

Respuesta

4

Oskar es correcto. Dos hilos separados intentan inicializar la fábrica de sesión al mismo tiempo. Sugiero que ponga algo de bloqueo alrededor del código de inicialización, tal vez simplemente usando la palabra clave lock y un objeto de sincronización adecuado. Hemos utilizado un patrón de esta manera, utilizando una de las cerraduras de la biblioteca Wintellect PowerThreading:

using (_lock.WaitToRead()) 
{ 
    if (Factory != null) return Factory; 
} 
using (_lock.WaitToWrite()) 
{ 
    if (Factory != null) return Factory; 
    Factory = ConfigureFactory(); 
    return Factory; 
} 

Usted podría más simplemente utilizar la palabra clave lock y una doble comprobación de patrón de bloqueo de este modo:

class NestedSessionManager 
{ 
    internal static SessionManager _sessionManager; 
    private static readonly object _syncRoot = new object(); 

    internal static SessionManager sessionManager 
    { 
     get 
     { 
      if (_sessionManager != null) return _sessionManager; 
      lock (_syncRoot) 
      { 
       if (_sessionManager != null) return _sessionManager; 
       _sessionManager = new SessionManager(); 
       return _sessionManager; 
      } 
     } 
    } 
} 
+0

HI David, he agregado la muestra del código. Creo que estoy construyendo configuración varias veces desde los detalles de log4net. ¿Podrías aconsejarme? Gracias. –

+0

¿Qué hay del constructor en el controlador? ¿Puedes publicarlo? –

+0

HI David, se ha incluido el código de muestra del controlador. Muchas gracias. –

Cuestiones relacionadas