WeakReference - 我做得对吗?

时间:2012-02-22 11:57:55

标签: c# .net-4.0 weak-references

我有一个静态类,它暴露了一个事件:

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的实例尚未被处理(并且尚未注销)的情况下才执行处理程序。

1 个答案:

答案 0 :(得分: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,并删除所有死亡的fooo。

然后您只需要AnotherClass : IFoo,并使用Bar()实施来应用您的回调。

进一步强调:静态集合(包括事件)相当危险;您必须偶尔进行某种扫描以删除空项目,并尽可能在可能的情况下尽快取消订阅(例如,在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);
    }
}