Исключение Ninject в Parallel.Foreach

У меня есть фрагмент кода, который запускает Parallel.Foreach в списке элементов для обработки. Каждая итерация создает пару объектов, каждый из которых создает и удаляет свой собственный экземпляр Ninject IKernel. IKernel удаляется, когда объект готов, он работает.

Тем не менее, этот код отлично работает на моем ноутбуке с Windows 7, I7. Однако, когда я отправляю его на свой VPS под управлением Windows 2008, я получаю это исключение. Исключение не возникает на одной итерации, иногда оно проходит через 10 итераций и генерирует исключение, в других случаях оно проходит через сотни из них. Очевидно, это похоже на проблему с потоками, но это не происходит нигде, кроме моего VPS. Если это важно, он размещен в ASP.NET IIS.

System.AggregateException: One or more errors occurred. --->
System.ArgumentOutOfRangeException: Index was out of range. 
    Must be non-negative and less than the size of the collection.  
    Parameter name: index
        at System.Collections.Generic.List`1.RemoveAt(Int32 index)
        at Ninject.KernelBase.Dispose(Boolean disposing)

Вот фрагмент кода:

//Code that creates and disposes the Ninject kernel
using(ninjectInstance = new NinjectInstance())
{
    using (var unitOfWork = ninjectInstance.Kernel.Get<NinjectUnitOfWork>())
    {
        Init();
        continueValidation = Validate(tran, ofr);
    }
}

public class NinjectInstance : IDisposable
{
    public IKernel Kernel { get; private set; }

    public NinjectInstance() 
    {           
        Kernel = new StandardKernel(
           new NinjectSettings() { AllowNullInjection = true }, 
           new NinjectUnitOfWorkConfigModule());          
    }

    public void Dispose()
    {
        if (Kernel != null)
        {
            Kernel.Dispose();
        }
    }
}   

Редактировать 1 s работает.

Тем не менее, этот код отлично работает на моем ноутбуке с Windows 7, I7. Однако, когда я отправляю его на свой VPS под управлением Windows 2008, я получаю это исключение. Исключение не возникает на одной итерации, иногда оно проходит через 10 итераций и генерирует исключение, в других случаях оно проходит через сотни из них. Очевидно, это похоже на проблему с потоками, но это не происходит нигде, кроме моего VPS. Если это важно, он размещен в ASP.NET IIS.

System.AggregateException: One or more errors occurred. --->
System.ArgumentOutOfRangeException: Index was out of range. 
    Must be non-negative and less than the size of the collection.  
    Parameter name: index
        at System.Collections.Generic.List`1.RemoveAt(Int32 index)
        at Ninject.KernelBase.Dispose(Boolean disposing)

Вот фрагмент кода:

//Code that creates and disposes the Ninject kernel
using(ninjectInstance = new NinjectInstance())
{
    using (var unitOfWork = ninjectInstance.Kernel.Get<NinjectUnitOfWork>())
    {
        Init();
        continueValidation = Validate(tran, ofr);
    }
}

public class NinjectInstance : IDisposable
{
    public IKernel Kernel { get; private set; }

    public NinjectInstance() 
    {           
        Kernel = new StandardKernel(
           new NinjectSettings() { AllowNullInjection = true }, 
           new NinjectUnitOfWorkConfigModule());          
    }

    public void Dispose()
    {
        if (Kernel != null)
        {
            Kernel.Dispose();
        }
    }
}   

Изменить 1 s работает.

Тем не менее, этот код отлично работает на моем ноутбуке с Windows 7, I7. Однако, когда я отправляю его на свой VPS под управлением Windows 2008, я получаю это исключение. Исключение не возникает на одной итерации, иногда оно проходит через 10 итераций и генерирует исключение, в других случаях оно проходит через сотни из них. Очевидно, это похоже на проблему с потоками, но это не происходит нигде, кроме моего VPS. Если это важно, он размещен в ASP.NET IIS.

System.AggregateException: One or more errors occurred. --->
System.ArgumentOutOfRangeException: Index was out of range. 
    Must be non-negative and less than the size of the collection.  
    Parameter name: index
        at System.Collections.Generic.List`1.RemoveAt(Int32 index)
        at Ninject.KernelBase.Dispose(Boolean disposing)

Вот фрагмент кода:

//Code that creates and disposes the Ninject kernel
using(ninjectInstance = new NinjectInstance())
{
    using (var unitOfWork = ninjectInstance.Kernel.Get<NinjectUnitOfWork>())
    {
        Init();
        continueValidation = Validate(tran, ofr);
    }
}

public class NinjectInstance : IDisposable
{
    public IKernel Kernel { get; private set; }

    public NinjectInstance() 
    {           
        Kernel = new StandardKernel(
           new NinjectSettings() { AllowNullInjection = true }, 
           new NinjectUnitOfWorkConfigModule());          
    }

    public void Dispose()
    {
        if (Kernel != null)
        {
            Kernel.Dispose();
        }
    }
}   

Редактировать 1 в других случаях он пройдет через сотни из них. Очевидно, это похоже на проблему с потоками, но это не происходит нигде, кроме моего VPS. Если это важно, он размещен в ASP.NET IIS.

System.AggregateException: One or more errors occurred. --->
System.ArgumentOutOfRangeException: Index was out of range. 
    Must be non-negative and less than the size of the collection.  
    Parameter name: index
        at System.Collections.Generic.List`1.RemoveAt(Int32 index)
        at Ninject.KernelBase.Dispose(Boolean disposing)

Вот фрагмент кода:

//Code that creates and disposes the Ninject kernel
using(ninjectInstance = new NinjectInstance())
{
    using (var unitOfWork = ninjectInstance.Kernel.Get<NinjectUnitOfWork>())
    {
        Init();
        continueValidation = Validate(tran, ofr);
    }
}

public class NinjectInstance : IDisposable
{
    public IKernel Kernel { get; private set; }

    public NinjectInstance() 
    {           
        Kernel = new StandardKernel(
           new NinjectSettings() { AllowNullInjection = true }, 
           new NinjectUnitOfWorkConfigModule());          
    }

    public void Dispose()
    {
        if (Kernel != null)
        {
            Kernel.Dispose();
        }
    }
}   

Изменить 1 в других случаях он пройдет через сотни из них. Очевидно, это похоже на проблему с потоками, но это не происходит нигде, кроме моего VPS. Если это важно, он размещен в ASP.NET IIS.

System.AggregateException: One or more errors occurred. --->
System.ArgumentOutOfRangeException: Index was out of range. 
    Must be non-negative and less than the size of the collection.  
    Parameter name: index
        at System.Collections.Generic.List`1.RemoveAt(Int32 index)
        at Ninject.KernelBase.Dispose(Boolean disposing)

Вот фрагмент кода:

//Code that creates and disposes the Ninject kernel
using(ninjectInstance = new NinjectInstance())
{
    using (var unitOfWork = ninjectInstance.Kernel.Get<NinjectUnitOfWork>())
    {
        Init();
        continueValidation = Validate(tran, ofr);
    }
}

public class NinjectInstance : IDisposable
{
    public IKernel Kernel { get; private set; }

    public NinjectInstance() 
    {           
        Kernel = new StandardKernel(
           new NinjectSettings() { AllowNullInjection = true }, 
           new NinjectUnitOfWorkConfigModule());          
    }

    public void Dispose()
    {
        if (Kernel != null)
        {
            Kernel.Dispose();
        }
    }
}   

Изменить 1 Одно можно сказать наверняка: это проблема безопасности потоков, и мне не следует создавать более одного экземпляра IKernel для каждого приложения. Это вопрос понимания того, как настроить правильные области для обеспечения безопасности потоков Entity Framework Context, но с сохранением подхода типа UoW, когда несколько классов бизнес-уровня могут совместно использовать один и тот же контекст EF в области UoW в одном потоке.

7
задан e36M3 29 April 2011 в 12:24
поделиться