8

asp.net Web フォーム アプリケーションでバージョン 2.2.0.0 の Ninject を使用していますが、数百回の要求の後、Binding クラスの GetProvider メソッドで NullReferenceException がスローされることがあります。

スタック トレースの例: http://pastebin.com/BbhsPQMT

例外は、アプリケーションのストレス テストを行った場合にのみ発生し、通常は例外の発生元が異なります (個別のインターフェイスの解決)。

この問題が発生した理由を理解するために、Ninject のソース コードを調べて、デバッグ用のコード行をいくつか挿入しました。後になって、null になっているオブジェクトが Binding クラスの ProviderCallback プロパティであることを確認しました。

また、ProviderCallback プロパティが null に設定されているかどうかを理解するために、プロパティの set 演算子にいくつかのコードを追加しました。いくつかのテストを実行し、いくつかのメモリ ダンプを調べた後、ProviderCallback プロパティが null 値に設定されていないように見えるため、GC によってインスタンスが収集されていると思います。

どうしてこうなったのか、いまだによくわかりません…

どんな助けでも大歓迎です。

編集:例外がまだ発生するかどうかを確認するためだけに Ninject の最新バージョンにアップグレードしましたが、アプリケーションのストレス テスト後に同じ例外が発生しました: http://pastebin.com/YiaaZndz

4

1 に答える 1

2

このような動作を再現できないため、この問題の理由はわかりません。ただし、問題を特定するために実行できるいくつかの手順を次に示します。

あなたが言うように、問題はそれが原因ProviderCallbackですnullnullGC はプロパティに割り当てられないため、これは GC が原因ではありません。代わりに、既に破棄された例外またはその他の奇妙な動作が発生します。ただし、これが発生する理由は他にもいくつかあります。

  1. Nullはいつか割り当てられますが、これはすでに確認済みであるため、これは理由ではありません。
  2. まったく割り当てられませんでした。
  3. 新しいBindingConfigurationは後で作成されます。

BindingConfiguration3 番目のポイントは、コンストラクターにブレークポイントを追加することで簡単に確認できます。カーネルが正常に構成され、オブジェクトの解決を開始した後は、もう呼び出さないでください。

2 番目の問題については、カーネル構成の後に次を実行します。

var kernel = your fully configured kernel;
var bindingsField = typeof(KernelBase).GetField("bindings", BindingFlags.NonPublic | BindingFlags.Instance);
var bindings = bindingsField.GetValue(kernel) as IEnumerable<KeyValuePair<Type, ICollection<IBinding>>>;

foreach (var bindingsEntry in bindings
    .Where(bindingsEntry => bindingsEntry.Value
        .Any(binding => binding.BindingConfiguration.ProviderCallback == null)))
{
    throw new Exception(string.Format("No Provider callback defined for {0}.", bindingsEntry.Key));
}
于 2012-11-20T18:07:01.830 に答える