2009-07-29 19 views
1

2つの変数を持つシンプルなクラスと、OnTimerTickから呼び出されるClose関数があります。ごくまれに、Close()関数でNullReferenceExceptionが発生していますが、これらの機会が何であるかを理解できません。誰かが説明できますか?System.Windows.Forms.TimerティックイベントでNullReferenceExceptionが発生する

System.Windows.Forms.Timer timer = new Timer(); 
//timer.Tick is wired up in Constructor to OnTimerTick 

private void OnTimerTick(object sender, EventArgs e) 
{ 
    timer.Tick -= OnTimerTick; 
    Close(); 
} 

private void Close() 
{ 
    if (varOne != null) 
    { 
     varOne.SomeEvent -= onSomeEvent; 
     varOne.Dispose(); 
     varOne = null; 
    } 

    if (varTwo != null) 
    { 
     varTwo.AnotherEvent -= onAnotherEvent; 
     varTwo.Dispose(); 
     varTwo = null; 
    } 
} 
+0

これはおそらくvarOneとvarTwoの種類に大きく依存します。 –

+0

デバッガで例外が発生した行は表示されませんか? –

+0

@monkey_p 私はデバッグセッション中にそれを見つけたことはありません。 – Raminder

答えて

1

他のスレッドがあなたの変数を変異されていないと仮定すると、onSomeEventonAnotherEventは、現在のインスタンス上にあると仮定して(すなわち、そこにnull参照のチャンスは)、そしておそらく最も可能性が高い事はDispose()が投げているということではありません?

これは可能です - 通常、エラー状態にあるとき(実際にはWCFを悩ませます)。処理をラップしてみてください。

ああ; varTwoにはシンプルなイベントハンドラがあると仮定しています。それはまた、完全に可能ですイベントの購読を中止するには、例えば、それはEventHandlerListを使用していると、すでにそれを離れて投げた場合...

だから一緒にそれらを入れて、何かのように:

// very paranoid cleanup 
try {varOne.SomeEvent -= onSomeEvent; } 
catch (Exception ex) { Trace.WriteLine(ex); } // best endeavours... 
try { varOne.Dispose(); } 
catch (Exception ex) { Trace.WriteLine(ex); } // best endeavours... 

は通常、パラノイアのこのタイプは必要ありません。しかしそれは時々ある。

+0

まあ、スタックトレースは、Close関数がスローすることを示しています。 DisposeまたはEvent unsubscribeの場合、スタックトレースに反映されるべきではありません。 – Raminder

+0

スタックトレースが存在する可能性があります。特に、(JIT)インライン展開などの最適化を伴うリリースで。 –

+0

さて、スタックトレースは私の場合にありました。 – Raminder

関連する問題