2

最近、1 つのハンドラーを 2 回クエリするとどうなるかという質問を受けました。コードをお見せしましょう:

 public delegate void OpenEventHandler(object sender, EventArgs e);

 public class MyWindow
 {
     public event OpenEventHandler Open;

     public void OpenWindow()
     {
         if (Open != null)
         {
             Open(this, new EventArgs());
         }
     }
 }

 public class TwoDelegates
 {
     public static void HandleOpen(Object sender, EventArgs e)
     {
         Console.WriteLine("Birds fly");
         (sender as MyWindow).Open -= HandleOpen;
     }

     public static void Run()
     {
         var window = new MyWindow();
         window.Open += HandleOpen;
         window.Open += HandleOpen;

         window.OpenWindow();
         Console.ReadKey();
     }
 }

なぜ文字列がまだ 2 回印刷されるのだろうか。最初の呼び出しリストは、同じデリゲート参照を持つ 2 つの項目で構成されていますが、最初の実行後にクリーンアップされ、2 番目の呼び出しが表示されます。

アップデート1:

シンプルでも-=エントリを1つだけ削除するようです:

 var window = new MyWindow();

 window.Open += HandleOpen;
 window.Open += HandleOpen;

 Console.WriteLine(window.getHandlers().Count());
 window.Open -= HandleOpen;
 Console.WriteLine(window.getHandlers().Count());

VS2010 のデバッグ モードでも、window.Open内部プロパティを確認すると、カウントが 0 の空の呼び出しリストが表示されます。VS に表示されるデバッグ情報の魔法のようです。

4

2 に答える 2

1

デリゲートがイベント ハンドラーを起動する方法の問題です。起動を開始する前に、内部デリゲート リストのコピーを取得します。その結果、同じイベントのイベント ハンドラー内でイベントのイベント ハンドラーを追加または削除すると、現在の呼び出しではなく、そのイベントの将来の呼び出しにのみ影響します。

于 2013-04-24T15:43:08.237 に答える