У меня есть фрагмент кода, который запускает 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 в одном потоке.