2017-06-28 2 views
0

私のコードでは単純なTimerを使用しています。コールバックは、時間が経過すると呼び出されます。System.ComponentModel.ComponentのDisposeメソッドは、イベントコールバックを解放しますか?

public TimerViewModel(int interval) { 
    m_timer = new Timer(interval); 
    m_timer.Elapsed += timer_Elapsed; 
    // Other stuff. 
} 

その後、私は、私はタイマーを配置またはそれはとにかく行われる前に今、私は私がm_timer.Elapsed -= timer_Elapsedと私のコールバックの登録を解除することが出来るのですかどうかを知りたい

public void Dispose() { 
    m_timer.Dispose(); 
    // Dispose some more stuff. 
} 

私のクラスを配置disposeメソッドを持っていますタイマーはメソッドを処理していますか?

TimersについてのMSDNサイトとComponentについてのMSDNサイトを読んでいますが、どちらも、その意味でDisposeメソッド「コンポーネントによって使用されているすべてのリソースを解放します」と記載されています。

したがって、Timer.Dispose()メソッドは自分のコールバックを解放しますか?

+0

他の誰もハンドラを参照していない場合、最終的にgcによって削除されます。 – NtFreX

+0

'Timer'を処理すると、静的でないハンドラはすべて消去されます。しかし、私が代わりに 'WeakEvent'を使用することを提案する場合に備えてください。 –

+0

これは必ずしも必要ではないはずです.TimerViewModelオブジェクトとタイマーの両方で同時にガベージコレクションが行われることが予想されます。これは、波及する可能性があり、TimerViewModelオブジェクトがどのように参照されているのかわかりませんが、配置されたオブジェクトへの参照を保持することは決して賢明ではありません。 –

答えて

0

私はハンドラを登録インスタンスはまた、(私はタイマーがメソッドを処分だそれにあなたのためのハンドラの登録を解除しないことをかなり確信している)して登録を解除することを、これは一般的に行われていると思う:

public void Dispose() { 
    m_timer.Elapsed -= timer_Elapsed; 
    m_timer.Dispose(); 
} 

しかしTimerViewModelm_timerの参照を所有しているようなケースでは、タイマーインスタンスの有効期間がTimerViewModelインスタンスの存続期間に接続されるため、これは重要ではないと私は考えています。このハンドラの登録を忘れると、両方のインスタンスがともに(一緒に)ガベージコレクションされるため、それほど問題にはなりません。

timer-instanceがviewmodelに渡されたり、他のオブジェクトによって参照が保持されるように、ある程度公開されている場合に問題が発生します。その場合、別のオブジェクトに参照があるためタイマーがガベージコレクションできないため、ビューモデルがガベージコレクションできないときにメモリリークが発生する可能性があります。

しかし、あなたが登録したすべてのハンドラを登録解除してください。

しかし、あなたのビューモデルをIDisposableにしないでください。 vm-instanceだけがtimer-instance-referenceを保持できることを確認してから、タイマの登録を解除して、タイマをすべて破棄することは無視できます。これらのビューモデルをたくさん作成して、実際にはメモリフットプリントを常に低く保たなければならない場合を除きます。それはガベージコレクションされ、とにかく、ビューモデルへの参照が削除されます。 IDisposableは、コンポーネントがイメージのセットをループするときや、別のビットマップをメモリにロードする前に解放する必要がある場合など、すぐにリソースをクリーンアップする必要があるときに主に使用されます。

関連する問題