3

私はWindowsFormアプリケーション「バウンスボール」を持っているので、各ティックでボールを動かすため、フォームのタイマーがあります。

私のフォーム c'tor には、次のコードがあります。

public Form1(){

  timer = new Timer();
  timerHandler = new EventHandler(timerTick);
  timer.Tick += timerHandler;
  timer.Enabled = true;
}

ユーザーがこのアプリケーションを閉じるときに、「EventHandler」を削除する必要がありますか? 終了ボタンがあるので、ユーザーがそれをクリックすると、アプリケーションを本当に終了するかどうかを尋ねるポップアップ ダイアログが表示されます。彼が [はい] をクリックした場合、私はアプリケーションを閉じます。それ以外の場合は何も起こりません。

だから私のExit Buttonコードで私はこのコードを書いた:

DialogResult result= MessageBox.Show("Do you really want to quit?", "Exit",  
                                     MessageBoxButtons.YesNo);
        if (result == DialogResult.Yes)
        {
             timer.Tick -= timerHandler;
             this.close();
        }

アプリケーションが閉じたときに timerHandler または GC が彼を破壊したことを心配する必要がありますか?

4

1 に答える 1

8

ユーザーがこのアプリケーションを閉じるときに、「EventHandler」を削除する必要がありますか?

いいえ、必要ありません。何よりも、アプリケーション全体が停止している場合、それはプロセスが停止することを意味するため、関係ありません。

しかし、そうでない場合でも、タイマーはフォームと同時にガベージ コレクションの対象となります。そのため、イベント ハンドラーがオブジェクトを必要以上に長く存続させることはありませんtimer(もちろん、変数がインスタンス変数であると仮定しています。)

編集:上記は、ガベージコレクションの側面に対処しているだけです。さらに考えてみると、ここに競合状態がある可能があります (実装の詳細はわかりません): フォームが閉じられて暗黙的に破棄された後、タイマーがカチカチ音をたてる場合、イベント ループの実行が停止する前に、次のことができます。破棄されたフォーム上でボールを動かそうとするタイマーティックで終わりますが、失敗します。

これに対処する最善の方法は、ティック ハンドラー (IMO) を削除することではありません。フォームが破棄されるときに (つまり、Disposeメソッド内で) タイマーを破棄することです。その面では完全に確かです)。

これは、物事がガベージ コレクションされるかどうかの問題ではありません。(フォームが破棄されたために) 適切でなくなったときにイベント ハンドラーが呼び出されるかどうかです。フォームを閉じるとすぐにイベント ループがシャットダウンされる場合は問題ありませんが、それは確かではありません。

于 2013-01-12T12:52:13.580 に答える