zoukankan      html  css  js  c++  java
  • .NET基础扩展系列如何获取事件的响应函数列表

        很多对象实现了IDispose接口的, 例如Socket对象. 在使用后, 需要及时调用Dispose()方法销毁.

    但是如果对象上的事件注册了事件响应函数, 那么就必须等待事件响应函数所在的对象回收以后, 它才能回收, 这个很容易导致程序出问题.

    所以比较理想的方案是在调用Dispose()之前, 把时间的事件响应函数注销掉.  这个就ok了.

       

        但是对象的事件响应函数可以添加多个, 而且一个事件可能在若干个对象中被注册了响应函数, 如何获取调用函数的列表呢, 然后住校呢.

        <CLR VIA C#>的事件一章, 详细讲解了.net的事件是通过字段+方法来实现的. 也就是说, 事件会被翻译成一个对应的委托私有字段.

    那么我们如果能够获取到委托的值, 就能获取到响应函数列表了.

    static EventHandler<EventArgs> GetEventHandler(object classInstance, string eventName)
    {
        Type classType = classInstance.GetType();
        FieldInfo eventField = classType.GetField(eventName, BindingFlags.GetField | BindingFlags.NonPublic | BindingFlags.Instance);
    
        EventHandler<EventArgs> eventDelegate = (EventHandler<EventArgs>)eventField.GetValue(classInstance);
    
        // eventDelegate will be null if no listeners are attached to the event
        if (eventDelegate == null)
        {
            return null;
        }
    
        return eventDelegate;
    }

    这段代码就是获取事件对应委托的.

    获取到委托以后, 调用委托的GetInvocationList()方法, 就可以获得响应函数列表了, 然后强制转换成对应的事件类型, 然后对事件执行-=操作, 就可以了.
    代码如下:

    Delegate[] dgs = eventDelegate.GetInvocationList(); 
    foreach (Delegate dg in dgs) 
    { 
    EventHandler
    <EventArgs> eh = (dg as EventHandler<EventArgs>); host.TestEvent -= eh; }

    不过需要注意的是: .net中, 还提供属性事件: 也即是会被.net翻译成属性的事件, 具体可以看MSDN中对于事件的介绍中, 专门有一节介绍了属性事件.

    一般属性事件适用于WinForm程序.

    获取属性事件的响应函数列表的过程类型, 只是把:

    FieldInfo eventField = classType.GetField(eventName, BindingFlags.GetField | BindingFlags.NonPublic | BindingFlags.Instance);

    替换成:

    PropertyInfo propertyInfo = (typeof(EventHost)).GetProperty(eventNameBindingFlags.Instance | BindingFlags.NonPublic ); 

    其实就是从获取字段信息变成获取属性信息.

  • 相关阅读:
    模板与继承之艺术——空基类优化
    模板的多态(静多态)威力
    Linux在vi编辑模式下如何查找
    PHP var_dump() 函数
    PHP empty() 函数
    IOS连接代理后自动关闭
    charles:屏蔽web网页的抓包信息(proxy)
    Python-unittest单元测试框架总结
    fiddler过滤域名:仅显示指定的域名
    Java中System.getProperties()方法获取的系统属性
  • 原文地址:https://www.cnblogs.com/dunnice/p/2406458.html
Copyright © 2011-2022 走看看