2

複数のフォームを持つ C# アプリケーションに取り組んでいます。
フォームの 1 つを開くと、次のようなイベント リスナーを追加しますSomeClass.MotionCompleted += new EventHandler(HandlerMethod);。MotionCompleted イベントは静的イベントです。

このフォームを閉じた後も、イベントが発生したときに HandlerMethod が呼び出され、フォーム上の存在しない何かを更新しようとするため、例外が発生することに気付きました。

フォームがもう存在しない場合でも、イベントリスナーはどのように存在し、イベントに応答できますか? form.Close() または this.Close() が呼び出されたら、イベント リスナを自動的にアンフックして、もう呼び出されないようにするべきではありませんか?

4

9 に答える 9

6

それは静的イベントの悪です!:)そこに管理されたリークがあります。

フォームのOnClosingをオーバーライドし、ハンドラーの登録を解除します。

protected override void OnClosing(CancelEventArgs e) {
    SomeClass.MotionCompleted -= new EventHandler(HandlerMethod);
}
于 2010-11-05T13:58:37.040 に答える
2
Someclass.MotionCompleted -= new EventHandler(HandlerMethod);

この記事では、C# のイベントに関する多くのヒントを紹介しています: http://www.yoda.arachsys.com/csharp/events.html

于 2010-11-05T13:58:00.770 に答える
1

すべての重複した回答に追加するには、次の方法でフックを解除することもできます。

SomeClass.MotionCompleted -= HandlerMethod;

出力アセンブリ コードは、-= HandlerMethodまたはを使用しても同じです-= new EventHandler(HandlerMethod)

于 2010-11-05T15:02:36.573 に答える
0
SomeClass.MotionCompleted -= new EventHandler(HandlerMethod);

「+」を「-」に変更するだけです

于 2010-11-05T13:58:43.297 に答える
0

手動でフックを解除する必要があります。

SomeClass.MotionCompleted -= HandlerMethod;
于 2010-11-05T13:59:01.757 に答える
0

次のコードサンプルを使用できます。

SomeClass.MotionCompleted -= new EventHandler(HandlerMethod);

ただし、イベントを登録したオブジェクトを含むオブジェクトの同じインスタンスからイベントのフックを解除するように注意する必要がありますHandlerMethod

于 2010-11-05T13:59:15.577 に答える
0

次のように、イベントのフックを手動で解除する必要があります。 SomeClass.MotionCompleted -= new EventHandler(HandlerMethod);

于 2010-11-05T13:59:23.153 に答える
0

ではない正確に。イベントハンドラーがまだ存在するため、フォームはガベージコレクターによって収集されません。静的イベントハンドラーは、それ自体でフックが解除されることはありません。次のようなonClosingメソッドの形式で、割り当てられたイベントのフックを解除できます。

SomeClass.MotionCompleted -= new EventHandler(HandlerMethod);

その後、すべてが機能するはずです。

于 2010-11-05T13:59:58.257 に答える
0

イベントは強い参照です。明示的に逆参照しない限り、イベントはガベージ コレクションできません。

そのため、サブスクライブとサブスクライブ解除のメソッドを作成して、そのジョブを実行し、このフックを集中化することをお勧めします (フックを解放しないと、メモリ リークが発生します)。

private void subscribeAll()
{
  SomeClass.MotionCompleted += new EventHandler(HandlerMethod);
  // other subscription
}

private void unSubscribeAll()
{
  SomeClass.MotionCompleted -= new EventHandler(HandlerMethod);
  // other subscription
}
于 2010-11-05T14:02:25.663 に答える