C#语言:为什么WeakReference的或弱的事件模式? [英] C# language: why WeakReference or Weak Event Pattern?

查看:365
本文介绍了C#语言:为什么WeakReference的或弱的事件模式?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在读C#语言,第4版,它谈论的WeakReference 弱事件模式

I'm reading "The C# Language", 4th edition, it talks about WeakReference and Weak Event Pattern:

CHRISTIAN NAGEL:内存泄漏往往是从事件的错误使用造成的。如果客户对象附加到事件,但不会从他们分离,并给客户对象的引用不再使用,客户对象仍然不能被垃圾收集器,因为出版商引用保持回收。这可以通过(1)事件的拆卸被避免当客户对象不再使用,(2)的自定义实施添加删除使用的WeakReference 类控股委托,或访问(3)弱事件模式 。所使用WPF与IWeakEventListener接口

CHRISTIAN NAGEL: Memory leaks often result from wrong usage of events. If client objects attach to events but do not detach from them, and the reference to the client object is no longer used, the client object still cannot be reclaimed by the garbage collector because the reference by the publisher remains. This can be avoided by (1) detaching of events when the client object is no longer used, (2) a custom implementation of the add and remove accessors using the WeakReference class holding the delegate, or (3) the Weak Event pattern that is used by WPF with the IWeakEventListener interface.

我这里有疑惑:选项(2)的WeakReference 带来的 NO方便是在所有的,相对于选项(1)显式的事件分离,因为使用的WeakReference 还需要明确要求双方添加删除

I have doubts here: Option "(2) WeakReference" brings NO convenience at all, comparing to "option (1) detaching of events explictly", because using WeakReference still need explicitly calls both add and remove.

否则,即使事件处理程序的对象之一,被分配到空,赵氏孤儿的对象仍然会回应事件 - 这将导致意外的行为。

Otherwise, even if one of the event handler's object was assigned to null, the "orphan" object will still respond to the event - this will cause unexpected behavior.

请注意: 的WeakReference 不仅有助于垃圾收集在该事件处理程序对象将不会成为影响事件发布对象的方式; 的WeakReference 不强制事件处理程序的对象被回收。

Note: WeakReference only helps Garbage collection in the way that event handlers' objects will not become affected by event publisher objects; WeakReference does NOT force event handler objects get garbage collected.

类似的问题适用于弱事件模式了。

Similar issue applies to Weak Event pattern, too.

也许这是一个有点抽象,以约什 - 史密斯的Mediator模式(http://joshsmithonwpf.wordpress.com/2009/04/06/a-mediator-prototype-for-wpf-apps/)为例。

Maybe this is a bit abstract, take Josh Smith's Mediator pattern (http://joshsmithonwpf.wordpress.com/2009/04/06/a-mediator-prototype-for-wpf-apps/) as example.

public class Mediator //...
{
  public void Register(object message, Action<object> callback)
  {
    // notice: Mediator has no Unregister method
  }
  public void NotifyColleagues(object message, object parameter)
  {
    // ...
  }
}
public class ObjectA //...
{
  public string ObjectAText
  {
    get { return _objectAText; }
    set
    {
      //...
      _mediator.NotifyColleagues(MediatorMessages.ObjectASaidSomething, _objectAText);
    }
  }
}
public class ObjectB //...
{
  //...
  public ObjectB(Mediator mediator)
  {
    //...
    _mediator.Register(
      MediatorMessages.ObjectASaidSomething,
      param =>
      {
        // handling event ObjectASaidSomething
      });
  }
}

如果我们有

ObjectA objectA = new ObjectA();
ObjectB objectB1st = new objectB();
objectA.ObjectAText = "John"; // objectB1st will respond to this event.

objectB1st = null; // due to delay of garbage collection, the object is actually still in memory

ObjectB objectB2nd = new objectB();
objectA.ObjectAText = "Jane"; // both objectB1st and objectB2nd will respond to this event!



难道最后一行导致意外的行为,由于的WeakReference

但是,如果中保类提供注销的方法(其实我实施一个),选项(2)的WeakReference 将没有区别选项(1)分离的事件显式。 (中介本身仍然是一个有用的模式,可以穿透的WPF和MVVM组件层层次)

But if the Mediator class provides "Unregister" method (actually I implemented one), "option (2) WeakReference" will be no difference to "option (1) detaching of events explictly". (Mediator itself is still a useful pattern, that can penetrate hierarchy of WPF or MVVM component layers )

推荐答案

如果我明白你都在问,那么有必要作出一些澄清。

If I understand what you are asking, then there is a need for some clarification.

否则,即使事件处理程序的对象之一,被分配到
空,赵氏孤儿的对象仍然会回应事件 - 这将
会导致意外行为。

Otherwise, even if one of the event handler's object was assigned to null, the "orphan" object will still respond to the event - this will cause unexpected behavior.

真的不。这不是意外的行为。这是完全预期的对象被调用,如果不明确地注销了。

Not really. This is not unexpected behavior. It is totally expected for the object to be called, if you do not unregister it explicitly.

弱事件的整个想法是一个安全网不守对象只是因为他们订阅了事件的记忆。它无关,与从事件注销对象时,它超出范围。

The whole idea of the weak events is a safety net for not keeping objects in memory only because they are subscribed to an event. It has nothing to do with unregistering the object from the event when it goes out of scope.

如果你需要做的后,既可以使用IDisposable模式和使用构建订户,或做明确的退订。

If you need to do the later, either use IDisposable pattern and "using" construct for the subscribers, or do explicit unsubscribe.

即弱活动是一个非常具体的问题的解决方案 - 允许对象,它被订阅了长活的对象(如GUI或者一些静态类)的垃圾收集

I.e. weak events are solution for a very specific problem - to allow garbage collection of objects, which were subscribed to a long living object (like GUI or some static class).

弱事件是不是来自即使在对象超出范围的那一刻自动unsibscribing。

Weak events are not about automatic unsibscribing from an even in the moment the object goes out of scope.

这篇关于C#语言:为什么WeakReference的或弱的事件模式?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆