7

我有一段代码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 上下文。

4

2 回答 2

5

请参阅http://groups.google.com/group/ninject/browse_thread/thread/574cd317d609e764

正如我告诉你的那样,Ninject 的 ctor 不是线程安全的 atm,除非你使用NOWEB! 如果多次创建/处理内核,您将不得不自己同步访问!我仍然建议重新设计您的 UoW 实施!

于 2011-04-29T00:12:15.090 回答
-1

它似乎ninjectInstance是一个实例变量。因此,在并行环境中,可能会为同一个实例ninjectInstance.Dispose()调用两次(调用Kernel.Dispose()不会将 Kernel 属性设置为nullKernel.Dispose() ),并且由于已被调用,因此该方法将失败。

也许你想要类似的东西

using (var ninjectInstance = new NinjectInstance()) {
..
}
于 2011-04-28T15:20:44.490 回答