2010-04-07 5 views
5

Je suis actuellement aux prises avec ce "collection a été modifiée, l'opération d'énumération peut ne pas exécuter" problème.NHibernate: la collection a été modifiée; opération d'énumération peut ne pas exécuter

J'ai recherché à propos de ce message d'erreur, et tout est lié à l'instruction foreach. J'ai les instructions foreach, mais elles représentent simplement les données. Je n'ai pas utilisé supprimer ou ajouter à l'intérieur de l'instruction foreach.

REMARQUE:

  1. L'erreur se produit au hasard (environ 4-5 fois par jour).
  2. L'application est le site Web de MVC.
  3. Il ya environ 5 utilisateurs qui utilisent cette application (environ 150 commandes par jour). Pourrait-il être certains utilisateurs d'autres ont modifié la collection, puis se produire cette erreur?
  4. Je log4net la configuration et les réglages se trouvent here
  5. Assurez-vous que le contrôleur a un constructeur public sans paramètre j'ai constructeur public parameterless dans AdminProductController

Est-ce que quelqu'un sait pourquoi cela arrive et Comment résoudre ce problème?

Un ami (Oskar) a mentionné que

« Théorie: Peut-être que le problème est que votre configuration et de l'usine session de est initialisé à la première demande après le redémarrage de l'application Si une deuxième requête arrive. avant que la première demande soit terminée, peut-être essaiera-t-elle également d'initialiser, puis provoquera ce problème d'une manière ou d'une autre. "

Merci beaucoup.

Daoming

Voici le message d'erreur:

System.InvalidOperationException Collection a été modifiée; l'opération d'énumération peut ne pas s'exécuter. System.InvalidOperationException: Une erreur s'est produite lors de la tentative de création d'un contrôleur de type 'WebController.Controllers.Admin.AdminProductController'. Assurez-vous que le contrôleur a un constructeur public sans paramètre. ---> System.Reflection.TargetInvocationException: Une exception a été lancée par la cible d'un appel. ---> NHibernate.MappingException: Impossible de configurer le magasin de données à partir du flux d'entrée DomainModel.Entities.Mappings.OrderProductVariant.hbm.xml ---> System.InvalidOperationException: la collection a été modifiée; l'opération d'énumération peut ne pas s'exécuter. à System.Collections.ArrayList.ArrayListEnumeratorSimple.MoveNext() à System.Xml.Schema.XmlSchemaSet.AddSchemaToSet (schéma de XmlSchema) à System.Xml.Schema.XmlSchemaSet.Add (String targetNamespace, schéma XmlSchema) au système .Xml.Schema.XmlSchemaSet.Add (schéma XmlSchema) à NHibernate.Cfg.Configuration.LoadMappingDocument (XmlReader hbmReader, nom de la chaîne) at NHibernate.Cfg.Configuration.AddInputStream (Stream xmlInputStream, nom de la chaîne) --- Fin de la trace de la pile d'exceptions interne --- à l'adresse NHibernate.Cfg.Configuration.LogAndThrow (exception exception) à NHibernate.Cfg.Configuration.AddInputStream (courant xmlInputStream, String name) à NHibernate.Cfg.Configuration.AddResource (chemin de chaîne, l'assemblage assemblage) à NHibernate.Cfg.Configuration.AddAssembly (assemblage de montage) à DomainModel.RepositoryBase ..ctor() à WebController.Controllers._baseController..ctor() à WebController.Controllers.Admin.AdminProductController..ctor() à System.RuntimeType.CreateInstanceImpl (PublicO booléen nly, skipVisibilityChecks booléennes, Boolean FillCache) --- Fin de trace de pile d'exception interne --- à System.RuntimeType.CreateInstanceImpl (Boolean publicOnly, skipVisibilityChecks booléennes, Boolean FillCache) à System.Activator.CreateInstance (type de type, booléen nonPublic) à System.Web.Mvc.DefaultControllerFactory.GetControllerInstance (RequestContext requestContext, Type controllerType) --- Fin de la trace de pile d'exception interne --- à System.Web.Mvc.DefaultControllerFactory.GetControllerInstance (RequestContext requestContext, Type controllerType) à System.Web.Mvc.DefaultControllerFactory.CreateController (RequestContext requestContext, String controllerName) à System.Web.Mvc.MvcHandler.ProcessRequestInit (HttpContextBase httpContext, ICon Troller contrôleur &, usine IControllerFactory &) à System.Web.Mvc.MvcHandler.BeginProcessRequest (HttpContextBase HttpContext, AsyncCallback de rappel, l'état de l'objet) à System.Web.HttpApplication.CallHandlerExecutionStep.System.Web.HttpApplication.IExecutionStep.Execute() à System.Web.HttpApplication.ExecuteStep (étape IExecutionStep, booléen & completedSynchronously)

Répondre

4

Oskar a raison. Deux threads distincts tentent d'initialiser la fabrique de sessions en même temps. Suggère que vous mettiez un verrou autour du code d'initialisation, peut-être simplement en utilisant le mot-clé lock et un objet de synchronisation approprié. Nous avons utilisé un modèle comme celui-ci, en utilisant l'un des verrous de la bibliothèque Wintellect PowerThreading:

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

Vous pouvez plus simplement il suffit d'utiliser le mot-clé lock et un motif de verrouillage revérifier comme ceci:

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, j'ai ajouté l'exemple de code. Je suppose que je construis la configuration plusieurs fois à partir des détails de log4net. Pourriez-vous me conseiller? Je vous remercie. –

+0

Qu'en est-il du constructeur dans le contrôleur - pouvez-vous poster cela? –

+0

HI David, le code du contrôleur a été inclus. Merci beaucoup. –

Questions connexes