【问题标题】:NHibernate: Collection was modified; enumeration operation may not executeNHibernate:集合已修改;枚举操作可能无法执行
【发布时间】:2010-04-12 15:43:17
【问题描述】:

我目前正在努力解决“集合已修改;枚举操作可能无法执行”的问题。

我搜索过这个错误信息,都和foreach语句有关。我确实有一些 foreach 语句,但它们只是简单地表示数据。我没有在 foreach 语句中使用任何 removeadd

注意:

  1. 错误随机发生(每天大约 4-5 次)。
  2. 应用程序是 MVC 网站。
  3. 大约有 5 个用户在操作这个应用程序(每天大约 150 个订单)。会不会是其他用户修改了收藏,然后出现这个错误?
  4. 我有log4net设置,可以在here找到设置
  5. 确保控制器有一个无参数的公共构造函数我确实在 AdminProductController 中有一个无参数的公共构造函数

有谁知道为什么会发生这种情况以及如何解决这个问题?

一位朋友(奥斯卡)提到

“理论:也许问题在于 您的配置和会话工厂 在第一个请求时初始化 应用程序重新启动后。如果一秒钟 请求在第一个之前进入 请求已完成,也许它会 也尝试初始化然后 以某种方式触发了这个问题。”

非常感谢。

道明

这是错误信息:

System.InvalidOperationException 收藏已修改;枚举操作可能无法执行。 System.InvalidOperationException:尝试创建类型为“WebController.Controllers.Admin.AdminProductController”的控制器时发生错误。确保控制器有一个无参数的公共构造函数。 ---> System.Reflection.TargetInvocationException:调用的目标已抛出异常。 ---> NHibernate.MappingException:无法从输入流 DomainModel.Entities.Mappings.OrderProductVariant.hbm.xml 配置数据存储 ---> System.InvalidOperationException:集合已修改;枚举操作可能无法执行。 在 System.Collections.ArrayList.ArrayListEnumeratorSimple.MoveNext() 在 System.Xml.Schema.XmlSchemaSet.AddSchemaToSet(XmlSchema 架构) 在 System.Xml.Schema.XmlSchemaSet.Add(字符串 targetNamespace,XmlSchema 架构) 在 System.Xml.Schema.XmlSchemaSet.Add(XmlSchema 架构) 在 NHibernate.Cfg.Configuration.LoadMappingDocument(XmlReader hbmReader,字符串名称) 在 NHibernate.Cfg.Configuration.AddInputStream(流 xmlInputStream,字符串名称) --- 内部异常堆栈跟踪结束 --- 在 NHibernate.Cfg.Configuration.LogAndThrow(异常异常) 在 NHibernate.Cfg.Configuration.AddInputStream(流 xmlInputStream,字符串名称) 在 NHibernate.Cfg.Configuration.AddResource(字符串路径,程序集程序集) 在 NHibernate.Cfg.Configuration.AddAssembly(程序集程序集) 在 DomainModel.RepositoryBase..ctor() 在 WebController.Controllers._baseController..ctor() 在 WebController.Controllers.Admin.AdminProductController..ctor() 在 System.RuntimeType.CreateInstanceImpl(布尔 publicOnly,布尔 skipVisibilityChecks,布尔填充缓存) --- 内部异常堆栈跟踪结束 --- 在 System.RuntimeType.CreateInstanceImpl(布尔 publicOnly,布尔 skipVisibilityChecks,布尔填充缓存) 在 System.Activator.CreateInstance(类型类型,布尔非公共) 在 System.Web.Mvc.DefaultControllerFactory.GetControllerInstance(RequestContext requestContext,类型 controllerType) --- 内部异常堆栈跟踪结束 --- 在 System.Web.Mvc.DefaultControllerFactory.GetControllerInstance(RequestContext requestContext,类型 controllerType) 在 System.Web.Mvc.DefaultControllerFactory.CreateController(RequestContext requestContext,字符串控制器名称) 在 System.Web.Mvc.MvcHandler.ProcessRequestInit(HttpContextBase httpContext,IController& 控制器,IControllerFactory& 工厂) 在 System.Web.Mvc.MvcHandler.BeginProcessRequest(HttpContextBase httpContext,AsyncCallback 回调,对象状态) 在 System.Web.HttpApplication.CallHandlerExecutionStep.System.Web.HttpApplication.IExecutionStep.Execute() 在 System.Web.HttpApplication.ExecuteStep(IExecutionStep step, Boolean& completedSynchronously)

【问题讨论】:

    标签: nhibernate


    【解决方案1】:

    奥斯卡是对的。两个单独的线程试图同时初始化会话工厂。建议您在初始化代码周围加一些锁,也许只是使用lock 关键字和合适的同步对象。我们使用了这样的模式,使用 Wintellect PowerThreading 库中的一个锁:

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

    您可以更简单地使用 lock 关键字和双重检查锁定模式,如下所示:

    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;
                }
            }
        }
    }
    

    【讨论】:

    • 嗨大卫,我已经添加了代码示例。我想我正在从 log4net 详细信息中多次构建配置。你能给我建议吗?谢谢。
    • 控制器中的构造函数怎么样 - 你能发布吗?
    • 嗨大卫,控制器示例代码已包含在内。非常感谢。
    • 嗨大卫,我怎样才能在现有代码中实现锁定?能给我提供一个样品吗?
    • 非常感谢。大卫。我现在知道如何使用 lock 关键字了。 :)
    猜你喜欢
    • 2015-06-17
    • 2020-02-07
    • 1970-01-01
    • 1970-01-01
    • 2022-06-17
    • 2011-10-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多