北京动点飞扬软件

近七年行业项目解决方案、专注WPF外包、SaaS外包、GoLang外包、H5外包、微信小程序外包、UE4外包、U3D外包等 案例丰富 — 您最值得信赖的合作伙伴 — 可签公司合同
  博客园  :: 首页  :: 新随笔  :: 联系 :: 订阅 订阅  :: 管理
内存泄露曾经、现在、以后在应用程序中永远也将是一个关注点,它的一个最初的起源是unsubscribed事件的处理程序。weak event pattern对内存的泄露能够起到一定的作用,但是还没有实施。在本文中,我们将看到 WPF使用 WeakEventManager 类时,所起到的作用。

  本篇文章是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

  它也展现出来了两个静态变量的方法:

  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
}