委托 事件 内存泄漏 弱引用 让人欢喜让人"忧"

      委托在.Net Framework中占据着非常重要的作用,它是.Net事件机制的关键,随着.Net2.0中匿名委托以及.Net3.5中的Lamda的表达式的应用等都可以看出委托所扮演的角色。虽然委托的优点数不胜数,但是反对使用以及建议小心谨慎使用的是大有人在,我对委托的使用是既不反对也不盲目而是小心谨慎.
      
      对于委托的小心谨慎主要就是委托使用不当常常会造成内存泄露,关于委托内存泄漏的解决方案有很多种,下面我从网上列出一些比较有名的两种:

http://www.codeproject.com/KB/cs/weakeventhandlerfactory.aspx
     
Solving the Problem with Events: Weak Event Handlers  
       
测试代码 事件定阅者
public class EventSubscriber
        {
            
//private string ProviderName;
            public EventSubscriber(EventProvider provider):this(provider,false)
            {
            }

            
public EventSubscriber(EventProvider provider,bool isNormal)
            {
                provider.MyEvent 
+= MyWeakEventHandler;

                
//ProviderName = provider.GetType().Name;
            }

            
private void MyWeakEventHandler(object sender, EventArgs e)
            {
                
//Console.WriteLine(ProviderName);
            }
        }
         
泛型WeakReference
    public class WeakReference<T> : WeakReference where T : class
    {
        
public WeakReference() : base(null) { }
        
public WeakReference(T target) : base(target) { }
        
public WeakReference(T target, bool trackResurrection) : base(target, trackResurrection) { }
        
public WeakReference(SerializationInfo info, StreamingContext context) : base(info, context) { }

        
public new T Target
        {
            
get
            {
                
return base.Target as T;
            }
            
set
            {
                
base.Target = value;
            }
        }

        
public static implicit operator T(WeakReference<T> o)
        {

            
if (o != null && o.Target != null)
                
return o.Target;
            
return null;
        }

        
public static implicit operator WeakReference<T>(T target)
        {
            
return new WeakReference<T>(target);
        }
    }

//事件提供者
    public class EventProvider 
    {
        
//弱引用事件处理器
        private WeakReference<EventHandler<EventArgs>> myEvent = new WeakReference<EventHandler<EventArgs>>(null);

        
public event EventHandler<EventArgs> MyEvent
        {
            add
            {
                myEvent.Target 
+= value;
            }
            remove
            {
                myEvent.Target 
-= value;
            }
        }
        
public void Notify(object sender, EventArgs e)
        {
            
if (myEvent != null && myEvent.Target != null)
                myEvent.Target(sender, e);
        }
    }
         
         上面的代码无论从性能,简洁还是优雅,应该是比上面提供的两个链接中都要好。为了解决消息总线的内存泄漏问题,为了提供一个更优雅的方案,春节前我整整化了1天的事间在网上找,确认用WeakRefernece 来解决问题,然后化2天时间反复搞性能测试,内存测试,我自认为我是第一人,,到了今天早上看到下面文章 ://www.cnblogs.com/Dah/archive/2007/03/11/671141.html ,比Solving the Problem with Events: Weak Event Handlers 这篇文章出来的还早一个月,比他的解决方法更好,比我的方案早了9个月,一方面让我为国人感到骄傲,另外一方面我很无语,这么好的文章竟然无人问津,只有几十个人浏览。。。。。。我希望像这种代码设计的经验和灵感,大家多Open 一点,互相学习,都少走弯路。。。。。。
原文地址:https://www.cnblogs.com/netcasewqs/p/1202504.html