2011-11-21 17 views
5

私は、C#のevenhandlerはリスナのリストを持っており、メッセージを送信するときにリストをループしていると思います。私の質問は、これが内部的にどのように機能するかです。リストをコピーする前にリストのコピーを作成しますか?そうであれば、リストがコピーされた後に誰かが登録を解除してもメッセージをまだ受信していない場合はどうなりますか?C#eventhandlerは内部的にどのように動作しますか?

メッセージは登録解除されていますか?

答えて

6

デリゲートは不変なので、デリゲートを呼び出すときには、サブスライラーのリストがわかっていて、修正されています。サブスクライブまたはサブスクライブを外すは、の代わりにイベントを支えるデリゲートを置き換えます。

これは確かにどちらかのためにマルチスレッドのシナリオでは、あなたが、退会後にイベントを受け取ることができるという意味ではない:デリゲートは

  • のスナップショットを呼び出される過程ですでにだった

    1. デリゲートは、すでに2で

    を呼び出す目的のために取得されていた、私はヌル-REFドゥリを防ぐために、(通常のパターンを意味しますNGの呼び出し):そのため

    var handler = SomeEvent; 
    // <===== another thread could unsubscribe at this point 
    if(handler != null) handler(sender, args); // <== or part way through this invoke 
    // (and it either case, have the event trigger even though they think they have 
    // unsubscribed) 
    

    あなたはイベントと複雑なマルチスレッドコードをコーディングしている場合、あなたはあなたが退会していると思います後を発射イベントは問題ではないことを防御的にこのようなコード必要があります。

    これらのニュアンスは、実際にはシングルスレッドコードには影響しません。

  • 関連する問題