NHibernate: коллекция была изменена; операция перечисления может не выполняться - PullRequest
5 голосов
/ 07 апреля 2010

Я в настоящее время борюсь с этой коллекцией " была изменена; операция перечисления может не выполнить проблему ".

Я искал об этом сообщении об ошибке, и все это связано с оператором foreach. У меня есть некоторые операторы foreach, но они просто представляют данные. Я не использовал remove или add внутри оператора foreach.

ПРИМЕЧАНИЕ:

  1. Произошла ошибка случайно (примерно 4-5 раз в день).
  2. Приложение - веб-сайт MVC.
  3. Приблизительно 5 пользователей используют это приложение (около 150 заказов в день). Может быть, другие пользователи изменили коллекцию, а затем произошла эта ошибка?
  4. У меня есть настройки log4net и настройки можно найти здесь
  5. Убедитесь, что у контроллера есть открытый конструктор без параметров У меня есть открытый конструктор без параметров в AdminProductController

Кто-нибудь знает, почему это происходит и как решить эту проблему?

Друг (Оскар) упомянул, что

"Теория: Может быть, проблема в том, что ваша конфигурация и фабрика сессий инициализируется по первому запросу после перезапуска приложения. Если второй запрос приходит раньше первого запрос закончен, может быть также попытайтесь инициализировать, а затем вызывая эту проблему как-то. "

Большое спасибо.

Daoming

Вот сообщение об ошибке:

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 (String targetNamespace, схема XmlSchema) в System.Xml.Schema.XmlSchemaSet.Add (схема XmlSchema) в NHibernate.Cfg.Configuration.LoadMappingDocument (XmlReader hbmReader, String name) в 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 () at System.RuntimeType.CreateInstanceImpl (логический publicOnly, логический skipVisibilityChecks, логический fillCache) --- Конец внутренней трассировки стека исключений --- at System.RuntimeType.CreateInstanceImpl (логический publicOnly, логический skipVisibilityChecks, логический fillCache) в System.Activator.CreateInstance (тип Type, логическое значение nonPublic) в System.Web.Mvc.DefaultControllerFactory.GetControllerInstance (RequestContext requestContext, Тип controllerType) --- Конец внутренней трассировки стека исключений --- в System.Web.Mvc.DefaultControllerFactory.GetControllerInstance (RequestContext requestContext, Тип controllerType) в System.Web.Mvc.DefaultControllerFactory.CreateController (RequestContext requestContext, String controllerName)в System.Web.Mvc.MvcHandler.ProcessRequestInit (HttpContextBase httpContext, IController & controller, IControllerFactory & factory) в System.Web.Mvc.MvcHandler.BeginProcessRequest (HttpContextBase httpContext, обратный вызов AsyncCallback, состояние объекта) в System.Web.HttpApplication.CallHandlerExecutionStep.System.Web.HttpApplication.IExecutionStep.Execute () в System.Web.HttpApplication.ExecuteStep (шаг IExecutionStep, логическое и завершено синхронно)

1 Ответ

4 голосов
/ 07 апреля 2010

Оскар прав. Два отдельных потока пытаются инициализировать фабрику сеансов одновременно. Предложите немного заблокировать код инициализации, возможно, просто используя ключевое слово 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;
            }
        }
    }
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...