2011-08-02 12 views
3

オブジェクトの一部のプロパティを更新するC#コードがあります。更新プロセスが完了したときに対応するためのイベントハンドラが定義されています。残念ながら、私はこのイベントが何回も解雇されていることを知りました。イベントハンドラが間違った時刻に設定されているため、これが起こっていると思われます。現在のところ、それは次のように設定されている:C#でイベントハンドラをクリアまたはチェックする

​​

により、コードの複雑さに、私はそれが設定すべき場所追跡の困難な時期を持っています。私はそれが以前に設定されていないイベントハンドラを設定するだけです。このため、私はこのような何かをしたい:

ClearEventHandlers(myObject); 

または

myObject.Update_Succeeded = null; 
myObject.Update_Succeeded += new EventHandler(myObject_Update_Succeeded); 

私がしようとしているものを達成する方法はありますか?

ありがとうございました!

答えて

0

あなたのオブジェクトの初期化、つまりコンストラクタでイベントハンドラを設定する方がよいでしょう。

6

はい、イベントの追加/削除アクセサをカスタマイズできます。 This articleには、これらのアクセサが記述されています。あなたは

myObject.Update_Succeeded -= new EventHandler(myObject_Update_Succeeded); 

それともあなたがしている場合、すべてのイベントハンドラを削除する方法のためにこれをチェックしてください以下のように減算演算子を使用してハンドラを削除することができるはず

class MyClass 
{ 
    private EventHandler _myEvent; 

    public event EventHandler MyEvent 
    { 
     [MethodImpl(MethodImplOptions.Synchronized)] 
     add 
     { 
      _myEvent = (EventHandler)Delegate.Combine(_myEvent, value); 
     } 
     [MethodImpl(MethodImplOptions.Synchronized)] 
     remove 
     { 
      _myEvent = (EventHandler)Delegate.Remove(_myEvent, value); 
     } 
    } 

    public void ClearMyEvent() { 
     _myEvent = null; 
    } 
    ... 
} 
+0

このようなアプローチはお勧めしません。イベントリスナーは、何も知らない他のイベントリスナーの登録を解除する必要はありません。 – Groo

+0

@Groo - 一般に、私は同意します。しかし、すべてのリスナーをクリアする方法が必要な時があります。 – CodeNaked

+0

私はこのような状況にまだいないことを告白する必要があります。そして、あなたが記述したパターンに従うBCLには、(私がこれまで見てきたオープンソースライブラリでも)単一のクラスはありません。 – Groo

2

適切な方法は、あなたは、もはやそれを使用した後、各イベントのハンドラを切り離すないようにする必要があります:

public class MyObjectListener 
{ 
    private readonly MyObject _object; 
    public class MyObjectListener(MyObject obj) 
    { 
      _object = obj; 
      Attach(); 
    } 

    // adds event handlers 
    private void Attach() 
    { 
     obj.UpdateSucceeded += UpdateSuceededHandler; 
     obj.UpdateFailed += UpdateFailedHandler; 
    } 

    // removes event handlers 
    private void Detach() 
    { 
     obj.UpdateSucceeded -= UpdateSuceededHandler; 
     obj.UpdateFailed -= UpdateFailedHandler; 
    } 

    ... 
} 

あなたが決定する必要があるのは、Detachメソッドを呼び出す場所だけです。たとえば、ハンドラ自身でそれを呼び出すことができます。

あなたが MyObjectListenerのユーザーが、それはもはや添付オブジェクトに耳を傾ける必要があること、それを言うんする可能性があります
 private void UpdateSuceededHandler(object sender, Data args) 
    { 
     Detach(); 
     // do something when it succeeds 
    } 

    private void UpdateFailedHandler(object sender, Data args) 
    { 
     Detach(); 
     // do something when it fails 
    } 

または、:

 public void StopListening() 
    { 
     Detach(); 
    } 

アンイベントを発生させるオブジェクトは、リスナーにイベント呼び出しリストを変更させるべきではありません。各イベントリスナーは、独自のイベントハンドラーのみを登録または登録解除する必要があります。

関連する問題