2012-02-22 8 views
1

私はイベントを公開する静的クラス、持っている:WeakReference - 私はそれを正しくしていますか?

public static class MyStaticClass 
{ 
    static bool myBool= false; 
    public static bool MyBool 
    { 
     get { return myBool; } 
     private set 
     { 
      myBool= value; 

      var handler = MyBoolChanged; 
      if (handler != null) 
       handler(null, null); 
     } 
    } 

    public static event EventHandler MyBoolChanged; 
} 

をそして私はこのパターンを使用して、それに登録しています:

class AnotherClass 
{  
    WeakReference _me; 

    public MyMethodInAnotherClass() 
    { 
     _me = new WeakReference(this); 
     MyStaticClass.MyBoolChanged+= 
       (_me.Target as AnotherClass).MyMethodInAnotherClassCallback;  
    } 

    private void MyMethodInAnotherClassCallback(some arguments) 
    { 
    } 
} 

私が達成したい何がMyStaticClassのみが実行されることですAnotherClassのインスタンスが破棄されていない場合(および登録解除されていない場合)

+2

いいえ、あなたは正しいことをしていません。 '_me.Target'を読んで自分自身への参照を明示的に与えてから、それをイベントサブスクリプションに格納します。 –

+0

ところで、静的イベントはメモリリークの**致命的**です。あなたは**あなたが欲しいものです**確かですか? –

+0

@MarcGravellいいえ、私は – UrbanEsc

答えて

2

私がこれを使用するのがわかる最も良い方法は、イベントを忘れて、何らかの種類のリストを使用することです。 List<WeakReference>としましょう。あなたは、その後かもしれない:と

interface IFoo { 
    void Bar(some args); 
} 

:追加のメカニズムと

static class Whatever { 
    private static readonly List<WeakReference> items=new List<WeakReference>(); 
    public static void Add(IFoo foo) { 
     if(foo != null) { 
      var newRef = new WeakReference(foo); 
      lock(items) { items.Add(newRef); } 
     } 
    } 
    public static void DoIt(some args) { 
     lock(items) { 
      foreach(var item in items) { 
       IFoo foo = item.IsAlive ? item.Target as IFoo : null; 
       if(foo != null) foo.Bar(some args); 
      } 
     } 
    } 
} 

特定IFooを削除すると、すべての死者FOOSを削除するには、TODOを残しました。

次に、コールバックを適用するBar()実装のAnotherClass : IFooが必要です。

その他の強調点:静的コレクション(イベントを含む)はかなり危険です。空のアイテムを取り除くために何らかの掃除をしなければならず、できるだけ早く(たとえばDispose())に拒否してください。例として:

public static void Remove(IFoo foo) { 
    lock (items) { // also remove any dead debris 
     items.RemoveAll(x => !x.IsAlive || x.Target == foo || x.Target == null); 
    } 
} 
関連する問題