本篇文章是WPF 4.5新特性的系列的一部分。
eneric Weak Event Manager
之前的WPF 4.5对于每个你想订阅的事件,必须创建一个a weak event manger,现在就不用这样了,你可以使用一个通用版本的WeakEventManager类。
需要作为一个通用的参数的类型的事件的源和类型的的dealed事件参数。
// Type parameters:
// TEventSource:
// The type that raises the event.
//
// TEventArgs:
// The type that holds the event data.
public class WeakEventManager<TEventSource, TEventArgs> :
WeakEventManager where TEventArgs : EventArgs
// TEventSource:
// The type that raises the event.
//
// TEventArgs:
// The type that holds the event data.
public class WeakEventManager<TEventSource, TEventArgs> :
WeakEventManager where TEventArgs : EventArgs
它也展现出来了两个静态变量的方法:
AddHandler在一个给定源的事件上添加一个处理程序,它将采用事件的名称作为参数。
RemoveHandler删除一个处理程序。
由于这是使用反射,在使用这个对象的时候,在性能上边会有一点小的开销。
订阅的接口
在之前的WPF 4.5中,weak-event的每个订阅必须实现IWeakEventListener,这个接口非常的简单:
public bool ReceiveWeakEvent(Type managerType, object sender, EventArgs e)
即使它能够简单快捷的实现,但是确实相当的单调的,如果想要实现更多它没有的需求,你只需要在订阅时传递一个委托即可!
举个例子:
比如说你有一个应用程序,在程序里面有主窗口,有时显示一些子窗口。当应用程序出现的时候,这些子窗口订阅激活了主窗口事件,通过使用传统的事件订 阅,您可以创建内存泄漏,如果您还没有注册它。在另一方面,你可以使用的WeakEventManager订阅此事件,你从来没有听说过了吧!
下面是一个例子使用的代码:
//Create 10 Mo to be more visible in the process explorer
public byte[] data = new byte[10 * 1024 * 1024];
public LeakingWindow()
{
InitializeComponent();
WeakEventManager<Window, EventArgs>
.AddHandler(App.Current.MainWindow, "Activated", MainWindow_Activated);
//Traditional event subscription: memory leak !
App.Current.MainWindow.Activated += MainWindow_Activated;
}
void MainWindow_Activated(object sender, EventArgs e)
{
//Do something here
}
public byte[] data = new byte[10 * 1024 * 1024];
public LeakingWindow()
{
InitializeComponent();
WeakEventManager<Window, EventArgs>
.AddHandler(App.Current.MainWindow, "Activated", MainWindow_Activated);
//Traditional event subscription: memory leak !
App.Current.MainWindow.Activated += MainWindow_Activated;
}
void MainWindow_Activated(object sender, EventArgs e)
{
//Do something here
}