日期:2014-05-17  浏览次数:20841 次

委托订阅取消不掉的问题?
本帖最后由 newmankind 于 2013-10-18 10:55:48 编辑
            string[] arr = GlobalStatic.marketChannel.dicMarketTransfer.Keys.ToArray();
            foreach (string _InstrumentID in arr)
            {
                GlobalStatic.marketChannel.dicMarketTransfer[_InstrumentID].PushMarketInfoEvent -= dicMarketTransfer[_InstrumentID].ReciveMarketInfo;
                
            }

 GlobalStatic.marketChannel.dicMarketTransfer[_InstrumentID] 和 dicMarketTransfer[_InstrumentID]. 均继承了以下接口(已实现)
    public interface IMarketTransfer
    {
        event PushMarketInfoEventHandler PushMarketInfoEvent;
        void ReciveMarketInfo(DataRow drMarket);
    }

按照官方文档,非匿名委托订阅 ,应该可以 用-=取消的啊,为什么取消不掉,求解,谢谢!
委托 取消订阅

------解决方案--------------------
引用:

//订阅
GlobalStatic.marketChannel.dicMarketTransfer[_instrumentID].PushMarketInfoEvent
                += new PushMarketInfoEventHandler(dicMarketTransfer[_instrumentID].ReciveMarketInfo);
//取消
GlobalStatic.marketChannel.dicMarketTransfer[_InstrumentID].PushMarketInfoEvent -= dicMarketTransfer[_InstrumentID].ReciveMarketInfo;

看看右边的项,订阅多了new,这样2个对象就不是同一个了。订阅改成下面的试试。
GlobalStatic.marketChannel.dicMarketTransfer[_instrumentID].PushMarketInfoEvent
                += dicMarketTransfer[_instrumentID].ReciveMarketInfo;

那样写没错,你自己对委托的概念不清楚,委托不是类,不能用类的思考方式去处理。

引用:
我疑惑就是 注册 和取消注册同时指向,同一个dictionary 的同一个实例的同一个函数,dicMarketTransfer[_InstrumentID].ReciveMarketInfo 应该这种写法表述不会有问题啊,为啥就取消不掉呢?

有几个疑点:
一、RegEvent()方法内部有注册事件,但没有看到取消,虽然注册的是空方法,不代表你实际方法也是空的。
二、pushMarketInfo可能为null,你却直接在ReciveMarketInfo内部使用,这是不安全的。
三、看定义,dicMarketTransfer似乎不是静态的,GlobalStatic.marketChannel.dicMarketTransfer似乎又是静态的,这两者似乎不是同一个对象,这里面是否存在变量偷换的情况。
四、GlobalStatic.marketChannel.dicMarketTransfer.Keys在注册和取消时,是否保证不曾发生过任何改变。