2009-05-03 56 views
17

イベントサブスクリプションが重複しないようにするにはどうすればよいでしょうか?このコード行が2か所で実行されると、イベントは2回実行されます。私は第三者イベントを2回購読するのを避けようとしています。私のデリゲートセッターでCで重複イベントサブスクリプションを避ける

theOBject.TheEvent += RunMyCode; 

、私は効果的に

theOBject.TheEvent -= RunMyCode; 
theOBject.TheEvent += RunMyCode; 

...これを実行することができますが、それは最善の方法は何ですか?

答えて

19

、最も効率的な方法は、あなたのイベント財産作り、このExampleのように、それに並行処理のロックを追加することです:

private EventHandler _theEvent; 
private object _eventLock = new object(); 
public event EventHandler TheEvent 
{ 
    add 
    { 
     lock (_eventLock) 
     { 
      _theEvent -= value; 
      _theEvent += value; 
     } 
    } 
    remove 
    { 
     lock (_eventLock) 
     { 
      _theEvent -= value; 
     } 
    } 
} 
+2

Dave Mortonがドメインを変更しました。新しいURLは次のとおりです。http://codinglight.blogspot.com/2009/02/preventing-duplicate-subscriptions-to.html –

+0

参考までにリンクが503になった場合は、ページを更新してください。それは私のためのいくつかの試行の後に読み込まれるようだ。 – Dan

1

オブジェクトのクラスのソースを所有している場合は、TheEventのInvocationListにアクセスできます。追加する前に、イベントの独自のアクセサアクセサを実装してチェックすることができます。

しかし、私はあなたのアプローチも素晴らしいと思います。

私が思う
2

あなたのコードのマルチスレッド化はされていますか?同時実行ロックはマルチスレッドの場合にのみ必要です。そのオーバーヘッドではない場合。

このように、購読を解除して購読するというあなたのアプローチは正しいです。

ありがとうございました

0

私は1つの詳細を除いてあなたのアプローチを使用します。私は、サブスクライバまたはtheObjectの新しいインスタンスを作成するときにイベントを購読する必要があると思います。これは、コードをよりストレートにします。したがって、適切なオブジェクトを処分した後で、必要なのはちょうど注意深く見ているだけです(pattenを処分するのが便利です)。

サードパーティのイベントを使用していると言われました。アドバイスされているとおり、追加/削除の方法を自分で実現することはできません。しかし、自分のイベントを持つあなた自身のクラスでは、あなたの問題を解決するためにイベントの追加/削除メソッドの独自の実現を定義する必要があります。

4

私はこれを前にしています....最後のサブスクライバが呼び出されるのは受け入れ可能であると仮定します。

using System; 
using System.Collections.Generic; 
using System.Linq; 
using System.Text; 

namespace ConsoleApplication2 
{ 
    class Program 
    { 
     static void Main(string[] args) 
     { 
      MyObject my = new MyObject(); 
      my.Changed += new EventHandler(my_Changed); 
      my.Changed += new EventHandler(my_Changed1); 

      my.Update(); 
      Console.ReadLine(); 
     } 

     static void my_Changed(object sender, EventArgs e) 
     { 
      Console.WriteLine("Hello"); 
     } 
     static void my_Changed1(object sender, EventArgs e) 
     { 
      Console.WriteLine("Hello1"); 
     } 
    } 
    public class MyObject 
    { 
     public MyObject() 
     { 
     } 
     private EventHandler ChangedEventHandler; 
     public event EventHandler Changed 
     { 
      add 
      { 
       ChangedEventHandler = value; 
      } 
      remove 
      { 
       ChangedEventHandler -= value; 
      } 
     } 
     public void Update() 
     { 
      OnChanged(); 
     } 

     private void OnChanged() 
     { 
      if (ChangedEventHandler != null) 
      { 
       ChangedEventHandler(this, null); 
      } 
     } 
    } 
} 
+4

いいえ、それを逃したかもしれないスピードリーダーのために、これは重要な線です。 ChangedEventHandler = value; + =の代わりに 一度の使用に適しています - 一部のケースで私のために働く可能性があります - ありがとうございます! – ScottCate

関連する問題