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 1 つ確かなことは、これはスレッド セーフの問題であり、アプリケーションごとに IKernel の複数のインスタンスを作成するべきではないということです。複数のビジネス レイヤー クラスが単一のスレッド内の UoW スコープ内で同じ EF コンテキストを共有できる UoW 型アプローチを維持しながら、Entity Framework コンテキスト スレッド セーフを実現するために適切なスコープを構成する方法を理解することが重要です。

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()2 回呼び出され (呼び出しによって Kernel プロパティがnullKernel.Dispose()に設定されない)、が既に呼び出されているため、メソッドが失敗する可能性があります。Kernel.Dispose()

多分あなたは次のようなものが欲しかった

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