2011-02-06 14 views
1

私はC#でカスタムイベントを作成したのは初めてです。それはなぜこの単純なケースでは動作しません私の心をboggles。C#の私のカスタムイベントがなぜ呼び出されないのですか?

私はサブスクライバを持つパブリッシャを持っています。私のメインプログラムでは、パブリッシャー1人と加入者2人をインスタンス化しました。私が持っているsubscriber.csで

static void Main() 
{ 
    Publisher publisher = new Publisher(); 
    Subscriber subscriber1 = new Subscriber("John"); 
    Subscriber subscriber2 = new Subscriber("Jane"); 

    publisher.AddNews("custom event NewPublication"); 
} 

加入者で ​​

私が持っている:

private String m_Name; 
private event NewPublication newPublication; 


public Subscriber(String name) { 
    m_Name = name; 
    newPublication += new NewPublication(subscriber_newPublication); 
} 

public void subscriber_newPublication(Publisher fromPublisher, String Message) { 
    MessageBox.Show(m_Name + " is notified for " + Message); 
} 

それはコンパイルが、ときaddNewsが呼び出されると、加入者は、イベントNewPublicationを受けるべきです実行中、イベントは発生しません。何故なの?コードを修正してコードを修正するにはどうすればよいですか?あなたは二つの異なるイベントを宣言した http://msdn.microsoft.com/en-us/library/w369ty8x.aspx

答えて

4

実際には2つのnewPublicationイベントがあります.1つはサブスクライバに、もう1つはパブリッシャにあります。あなたはパブリッシャーでそれを上げていますが、購読者は自分のイベントに登録するだけです。ここで

は、あなたの加入者クラスがどのように動作するかを示します。

public Subscriber Subscribe(String name) 
{ 
    return new Subscriber(name, this); 
} 

注:使用を容易にするため

private String m_Name; 
private Publisher m_Publisher; 

public Subscriber(String name, Publisher publisher) { 
    m_Name = name; 
    m_Publisher = publisher; 
    m_Publisher.newPublication += new NewPublication(subscriber_newPublication); 
} 

public void subscriber_newPublication(Publisher fromPublisher, String Message) { 
    MessageBox.Show(m_Name + " is notified for " + Message); 
} 

、あなたはそうのように、あなたのパブリッシャークラスに登録する方法を紹介したい場合があります接続されているがデタッチされていないイベントハンドラは、.NETアプリケーションでメモリリークを引き起こす可能性があります。必要がなくなったときにイベントハンドラを切り離すには、常に - =演算子を使用します(たとえば、WinFormsアプリケーションでは、通常、FormClosedイベントが発生したときにコントロールイベントのイベントハンドラを切り離します)。 Hereはそれを深く説明する良い記事であり、hereはメモリリークの検出方法を示すもう一つのものです。

アドバンスドイベントのコンセプトについては、thisシリーズの記事で説明しているように、F#やリアクションフレームワークのイベントモデル(メモリリークのない)を理解しておくとよいでしょう。

+0

+10イベントメモリリークありがとう:) – user310291

+0

@ user310291:私はF#とRx.NETのイベントモデルに言及するために投稿を更新しました。トピックを深く掘り下げたい場合は、基本をよく知っているように、それらを見てみることをお勧めします。あなたは彼らがいつ便利になるのか分からない。 :) – ShdNx

1

:MSDNのサンプルコードから本当に違う何

。サイト運営者インスタンスとサブスクライバインスタンスはで、は接続されていません。したがって、パブリッシャでイベントを発生させても、サブスクライバのハンドラはトリガされません。あなたがする必要がどのような

は概略的なものである:

publisher.newPublication += subscriber1.subscriber_newPublication; 
publisher.newPublication += subscriber2.subscriber_newPublication; 

置き、これらのクラスとAddNews()への呼び出しのインスタンス化の間にこのコード。

更新:はしたがってSubscriberクラスのnewPublicationの宣言は完全に無用であり、そのクラスから除去されなければなりません。必要に応じてPublisherインスタンスをSubscriberのコンストラクタに渡して、Subscriber内のイベント配線を作成することができます。しかし、一般的には、イベント配線コードをイベントパブリッシャーとイベントサブスクライバーの両方に保存することをお勧めします。

+0

ただし、これでは2つのイベントのいずれも接続されません。デリゲートは値型なので、ここでは、subscriber1.newPublicationとsubscriber2.newPublicationのイベントハンドラをpublisher.newPublicationにコピーするだけです。どちらの加入者にも追加されたイベントハンドラは、パブリッシャには表示されません。 – ShdNx

+0

@ShdNx Heh、そうですね、実際には、subscriber_newPublicationが実際に意味していました。バグに気づいてくれてありがとう。 –

関連する問題