2012-02-16 19 views
1

私は本当のバグを持っているかどうか、またそれが正しいかどうかのアドバイスを探しています:Ninjectのバグ?

私は非常にマルチスレッドプロセスを24時間実行しています。 NinjectによるThreadScopeで提供されるバインディングで注入されるオブジェクトがいくつかあります。

プロセスの負荷が増えたため、プロセスが頻繁にクラッシュし始めました。イベントログにエラーメッセージがこのでした:Ninjectのソースをダウンロードして、グーグルの後

> Framework Version: v4.0.30319 Description: The process was terminated 
> due to an unhandled exception. Exception Info: 
> System.NullReferenceException Stack: at 
> **Ninject.Activation.Caching.GarbageCollectionCachePruner.PruneCacheIfGarbageCollectorHasRun(System.Object)** 
> at System.Threading.ExecutionContext.runTryCode(System.Object) at 
> System.Runtime.CompilerServices.RuntimeHelpers.ExecuteCodeWithGuaranteedCleanup(TryCode, 
> CleanupCode, System.Object) at 
> System.Threading.ExecutionContext.Run(System.Threading.ExecutionContext, 
> System.Threading.ContextCallback, System.Object, Boolean) at 
> System.Threading._TimerCallback.PerformTimerCallback(System.Object) 

、誰でもあなたによって多少の問題のいずれかをNinjectまたは.NETフレームワークとの(ように見えます聴く)。

バインドキャッシュのプルーニングは、finally句で廃棄されたタイマーオブジェクトを再起動しようとしています。 そこ年前にそのロジックで問題を解決しようとする試みだったが、十分行っているようには見えない: http://groups.google.com/group/ninject/browse_frm/thread/cedf5d129120ee18/27119d7d3761eedd?tvc=1#27119d7d3761eedd

システムタイマーは、このMSDNの記事でどのように機能するか

Microsoftは説明していますhttp://msdn.microsoft.com/en-us/library/system.threading.timer.aspx

MSDNの記事によると、TimerCallbackが呼び出される前にGCがタイマーオブジェクトをクリーンアップした可能性があります。したがって、「finally」節でタイマーを再起動するとクラッシュします。

質問:これをNinjectコードでどのように修正できますか?このような場合のエラーを無視してください。新しいタイマーを作成する必要がありますか?私は別のことをしなければならないでしょうか?私は現在、エラーを無視するようにコードを修正しているので、プロセスがクラッシュするのを単に止めることができます...しかし、それが素晴らしい解決策ではないことを恐れて、アドバイスをいただければ幸いです。

関連記事:キャッシュ(Ninject)が配置されている競合状態が発生する2.2のバグがあり http://groups.google.com/group/ninject/browse_thread/thread/8cdf8362a41153c7

.NET 3.5 C# Bug with System.Timer System.ObjectDisposedException: Cannot access a disposed object

Ninject Garbage Collection

答えて

3

。これはとにかくNinjectを使用するための良い方法ではありませんし、いつでも避けるべきであるあなたが作成し、これをruntime-時にカーネルを配置されていない限り、あなたは何の問題もないはず、https://github.com/ninject/ninject/blob/fa46b56b683d5ddf570d00c1bd057ecfa0b3b487/src/Ninject/Activation/Caching/GarbageCollectionCachePruner.cs

通常を参照してください3.0

に固定されています。可能。そうすれば、この問題が発生する唯一の状況はシャットダウン時に発生するはずです。

+0

あなたのお返事ありがとうございます(とninjectですばらしい作業)。リンクのコードは私が使ってきたもので、クラッシュしています。タイマーオブジェクト自体は、PruneCacheIfGarbageCollectoinHasRun()関数に配置されています。 'finally'節は 'timer.Change'を呼び出そうとしていて、タイマーはすでに破棄されています。 – Igorek

+0

このバージョンの停止機能は2.2とは異なり、問題を解決する必要があります。しかし、もう一度http://msdn.microsoft.com/en-us/library/b97tkt95.aspxを参照してください。主な問題は、起動時にカーネルを作成し、シャットダウン時に破棄するのではなく、アプリケーション実行中にカーネルを廃棄することです。 –

+0

私のアプリケーションは、大きなループの各サイクルごとに複数のスレッドを開始しています。各スレッドは、データストアから取得したデータを処理しています。各スレッド内では、いくつかのインターフェイスを具体的な実装にバインドしています(各実装はスレッド固有です)。スレッドはすべてのループサイクルを行き来します。 – Igorek