委托 - 事件 - 内存泄漏 - 弱引用 让人欢喜让人"忧"
委托在.Net Framework中占据着非常重要的作用,它是.Net事件机制的关键,随着.Net2.0中匿名委托以及.Net3.5中的Lamda的表达式的应用等都可以看出委托所扮演的角色。虽然委托的优点数不胜数,但是反对使用以及建议小心谨慎使用的是大有人在,我对委托的使用是既不反对也不盲目而是小心谨慎.
对于委托的小心谨慎主要就是委托使用不当常常会造成内存泄露,关于委托内存泄漏的解决方案有很多种,下面我从网上列出一些比较有名的两种:
http://www.codeproject.com/KB/cs/weakeventhandlerfactory.aspx
对于委托的小心谨慎主要就是委托使用不当常常会造成内存泄露,关于委托内存泄漏的解决方案有很多种,下面我从网上列出一些比较有名的两种:
http://www.codeproject.com/KB/cs/weakeventhandlerfactory.aspx
Solving the Problem with Events: Weak Event Handlers
测试代码 事件定阅者
泛型WeakReference
//事件提供者
上面的代码无论从性能,简洁还是优雅,应该是比上面提供的两个链接中都要好。为了解决消息总线的内存泄漏问题,为了提供一个更优雅的方案,春节前我整整化了1天的事间在网上找,确认用WeakRefernece 来解决问题,然后化2天时间反复搞性能测试,内存测试,我自认为我是第一人,,到了今天早上看到下面文章 ://www.cnblogs.com/Dah/archive/2007/03/11/671141.html ,比Solving the Problem with Events: Weak Event Handlers 这篇文章出来的还早一个月,比他的解决方法更好,比我的方案早了9个月,一方面让我为国人感到骄傲,另外一方面我很无语,这么好的文章竟然无人问津,只有几十个人浏览。。。。。。我希望像这种代码设计的经验和灵感,大家多Open 一点,互相学习,都少走弯路。。。。。。
测试代码 事件定阅者
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);
}
}
{
//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 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);
}
}
{
//弱引用事件处理器
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 一点,互相学习,都少走弯路。。。。。。