在Parallel.Foreach中调用对象异常

本文关键字:对象 异常 调用 Parallel Foreach | 更新日期: 2023-09-27 17:53:25

我有一段代码,它在要处理的项目列表上运行Parallel.Foreach。每次迭代创建一对对象,每个对象实例化并处置它自己的Ninject IKernel实例。当对象完成它的工作时,IKernel被释放。

也就是说,这段代码在我的Windows 7、I7笔记本电脑上运行得非常好。然而,当我把它推出到我的VPS运行Windows 2008我得到这个例外。异常不会在同一次迭代中发生,有时它会经过10次迭代并抛出一个异常,有时它会经过数百次迭代。显然似乎是一个线程问题,但它不会发生在任何地方,但我的VPS。如果它是在ASP中托管的。净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上下文。

在Parallel.Foreach中调用对象异常

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

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

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

也许你想要像

using (var ninjectInstance = new NinjectInstance()) {
..
}