我有一段代码Parallel.Foreach
在要处理的项目列表上运行。每次迭代都会创建几个对象,每个对象都会实例化并处理它自己的 Ninject IKernel 实例。当对象完成它的工作时,IKernel 被释放。
也就是说,这段代码在我的 Windows 7、I7 笔记本电脑上运行良好。但是,当我将它推送到运行 Windows 2008 的 VPS 时,我得到了这个异常。异常不会在同一次迭代中发生,有时它会经历 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 可以肯定的是,这是一个线程安全问题,我不应该为每个应用程序创建多个 IKernel 实例。这是一个理解如何配置适当范围以实现实体框架上下文线程安全同时保留 UoW 类型方法的问题,其中多个业务层类可以在单个线程内的 UoW 范围内共享相同的 EF 上下文。