2013-05-03 14 views
9

私は製品情報の編集を可能にするプログラムを持っています。私はそれが編集フォームを閉じた後にメモリを解放していないことに気づいた。いくつかの調査の後、私はthisという質問を見つけました。この質問は、問題がイベント購読に掛かっている可能性があることを言います。すべてのイベントを登録解除してメモリを解放する

このフォームには約100以上のコントロールがあり、その多くは親コントロールによって購読されているカスタムイベントでカスタムされているため、わかりました。これにより、イベントサブスクリプションのかなり大きな階層が作成されます。だから私はこれらをリリースする方法を探して、そのイベントから退会することを可能にするthisを見つけました。

問題は、私はサブスクリプションのトンを持っています。フォームの終了時に、各イベントから1つずつ手動で購読を解除する必要がありますか?それとも少なくとも1つをリリースする方法がありますか?

+0

おそらく弱いイベントパターンに見て:http://msdn.microsoft.com/en-us/library /aa970850.aspx –

答えて

6

これを覚えておいてください:+=の左のオブジェクトは、+=の右辺にメソッドを含むオブジェクトを保持し続けます。つまり、が発生するオブジェクトイベントを処理するオブジェクト(フォームなど)が配置されている場合でも、イベントはが処理するオブジェクトを有効にします。

あなたが確保する必要があることは、すべてのイベントレイズャーがなくなったことです。

すべてのイベント調達者は、これらのイベントをサブスクライブし、同じFormクラスでコントロールすることが起こる場合は、あなたはは、フォームが閉じられたときに、手動ですべてのイベントハンドラを外しする必要はありません。

これは、登録する予定のイベントを発生させるコントロールがフォーム自体と同じ有効期間を持つためです。

サブスクライブしているオブジェクトよりも寿命の長いオブジェクトによって発生したイベントをサブスクライブする場合は、心配する必要があります。 サブスクライブしているオブジェクト(フォーム)は、そのフォーム(フォーム)が廃棄されるときに購読を解除する必要があります。

+0

状況では:Form => Control1 => Control2、それぞれのイベントに登録して、Control2が最初に実行されている限り、カスケードは正常で、すべてのイベントは適切に解放されるはずです。 – Nick

+0

@ニックはい、フォームに(直接的または間接的に)両方のコントロールが含まれている場合は正常です。フォームが破棄されたら、ライブオブジェクトからコントロールにアクセスすることはできませんが、フォームにはどこにも参照がないことを前提としています。そうすれば、それが処分されているかどうかは問題ではありません。それでも到達可能な場合、その場合はまだすべてのコントロールとともに生きています。したがって、どこにもフォームへのnull以外の参照がないことは非常に重要です! –

+0

[OK]をクリックすると、そのフォームへの他の参照がなく、メニューアイテムのクリックイベント内にフォームが作成されて表示されます。そのフォームが閉じられると、理論的には、すべての子コントロールは、それぞれのイベントとともに解放されるべきですか? – Nick

4

フォームとイベントがどれだけ長く生きるかによって異なります。

ただし、フォーム内のコントロールをループしてイベントを解放することができます。 存在しないイベントを誤って削除した場合でも、それは例外ではありません。

たとえば、これはすべてあなたのTextBox.KeyDown-イベントを取り除く方法です:

private void frm_FormClosed(object sender, FormClosedEventArgs e) 
    { 
    foreach (Control tb in this.Controls) 
    { 
     if (tb is TextBox) 
     { 
      TextBox tb1 = (TextBox)tb; 
      tb1.KeyDown -= TextBox_KeyDown; 
     } 
    } 
関連する問題