<i id='muusE'><tr id='muusE'><dt id='muusE'><q id='muusE'><span id='muusE'><b id='muusE'><form id='muusE'><ins id='muusE'></ins><ul id='muusE'></ul><sub id='muusE'></sub></form><legend id='muusE'></legend><bdo id='muusE'><pre id='muusE'><center id='muusE'></center></pre></bdo></b><th id='muusE'></th></span></q></dt></tr></i><div id='muusE'><tfoot id='muusE'></tfoot><dl id='muusE'><fieldset id='muusE'></fieldset></dl></div>
    <legend id='muusE'><style id='muusE'><dir id='muusE'><q id='muusE'></q></dir></style></legend>
  • <small id='muusE'></small><noframes id='muusE'>

      • <bdo id='muusE'></bdo><ul id='muusE'></ul>

      <tfoot id='muusE'></tfoot>

      1. 将所有标准事件处理程序替换为 WeakEventManager 或其变体是否安全?

        时间:2023-09-16
        <tfoot id='xWNDM'></tfoot>

          1. <i id='xWNDM'><tr id='xWNDM'><dt id='xWNDM'><q id='xWNDM'><span id='xWNDM'><b id='xWNDM'><form id='xWNDM'><ins id='xWNDM'></ins><ul id='xWNDM'></ul><sub id='xWNDM'></sub></form><legend id='xWNDM'></legend><bdo id='xWNDM'><pre id='xWNDM'><center id='xWNDM'></center></pre></bdo></b><th id='xWNDM'></th></span></q></dt></tr></i><div id='xWNDM'><tfoot id='xWNDM'></tfoot><dl id='xWNDM'><fieldset id='xWNDM'></fieldset></dl></div>
              <bdo id='xWNDM'></bdo><ul id='xWNDM'></ul>
                    <tbody id='xWNDM'></tbody>
                  <legend id='xWNDM'><style id='xWNDM'><dir id='xWNDM'><q id='xWNDM'></q></dir></style></legend>
                1. <small id='xWNDM'></small><noframes id='xWNDM'>

                  本文介绍了将所有标准事件处理程序替换为 WeakEventManager 或其变体是否安全?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着跟版网的小编来一起学习吧!

                  问题描述

                  标准事件处理程序(使用运算符 +=)是 内存泄漏 原因之一(如果它没有取消注册/处置(使用 -= 运算符)).

                  Standard event handler (with operator +=) is one of the memory leakage cause (if it is not unregistered/disposed (with -= operator)).

                  微软通过 WeakEventManager 及其继承方式解决了这个问题,例如:PropertyChangedEventManager、CollectionChangedEventManager、CurrentChangedEventManager、ErrorsChangedEventManager 等等.

                  And Microsoft solved it with WeakEventManager and its inheritance like: PropertyChangedEventManager, CollectionChangedEventManager, CurrentChangedEventManager, ErrorsChangedEventManager and so on.

                  内存泄漏的简单示例代码为:

                  public class EventCaller
                  {
                      public static event EventHandler MyEvent;
                      
                      public static void Call()
                      {
                          var handler = MyEvent;
                          if (handler != null)
                          {
                              handler(null, EventArgs.Empty);
                              Debug.WriteLine("=============");
                          }
                      }
                  }
                  
                  public class A
                  {
                      string myText;
                  
                      public A(string text)
                      {
                          myText = text;
                          EventCaller.MyEvent += OnCall;
                  
                          // Use code below and comment out code above to avoid memory leakage.
                          // System.Windows.WeakEventManager<EventCaller, EventArgs>.AddHandler(null, "MyEvent", OnCall);  
                      }
                      
                      void OnCall(object sender, EventArgs e)
                      {
                          Debug.WriteLine(myText);
                      }
                      
                      ~A()
                      {
                          Debug.WriteLine(myText + " destructor");
                      }
                  }
                  
                  void Main()
                  {
                      var a = new A("A");
                      var b = new A("B");
                      EventCaller.Call();
                      a = null;
                      GC.Collect();
                      EventCaller.Call();
                  }
                  

                  输出为:

                  A
                  B
                  +++++++
                  A
                  B
                  +++++++
                  

                  我们可以看到析构函数不会被调用.但是如果我们改变(通过注释未使用的代码):

                  We can see that the destructor will not be called. But if we change (by commenting the unused code) from:

                      EventCaller.MyEvent += OnCall;
                  

                      System.Windows.WeakEventManager<EventCaller, EventArgs>.AddHandler(null, "MyEvent", OnCall);  
                  

                  输出为:

                  A
                  B
                  +++++++
                  B
                  +++++++
                  A destructor
                  B destructor
                  

                  在 A 为空后,它的事件处理程序将不再被调用.没有 -= 操作符的 A 和 B 将在不再使用后被丢弃.

                  After A is nulled then its event handler will not be called anymore. A and B will be disposed after not be used anymore without -= operator.

                  1. 我是否可以安全地将所有 += 运算符替换为 System.Windows.WeakEventManager 以避免由于可能丢失事件注销和保存代码而导致的内存泄漏不应实现 IDisposable?

                  1. Can I safely replace all += operator with System.Windows.WeakEventManager to avoid memory leakage due to probably missing event unregistration and saving code by should not implement IDisposable?

                  如果真的不安全,我应该考虑或注意什么?

                  If it is not really safe, what should I consider or notice?

                  推荐答案

                  我可以安全地将所有 += 运算符替换为 System.Windows.WeakEventManager 以避免由于可能丢失事件注销和保存代码而导致的内存泄漏,不应该实现 IDisposable?

                  Can I safely replace all += operator with System.Windows.WeakEventManager to avoid memory leakage due to probably missing event unregistration and saving code by should not implement IDisposable?

                  你可以吗?大概.你应该?可能不是.如果您确实有对事件处理程序的强引用,那么如果事件的发布者比事件的订阅者的寿命更长,那么您应该更喜欢取消订阅它,而不是用弱事件替换强引用.使用弱事件有副作用.其中之一是性能.另一个是语义差异.关于为什么.NET Framework中的事件实现默认不使用弱事件模式,你可能想参考以下问答:

                  Can you? Probably. Should you? Probably not. If you do have a strong reference to an event handler you should prefer unsubscribe from it if the publisher of the event lives longer than the subscriber of the event rather than replacing the strong reference with a weak event. There are side effects of using weak events. One of them is performance. Another is the semantic difference. You may want to refer to the following question and answers about why the implementation of events in the .NET Framework does not use the weak event pattern by default:

                  为什么C#中事件的实现默认不使用弱事件模式?

                  在某些情况下,您当然应该使用弱事件模式.一种这样的场景是 WPF 中的数据绑定,其中源对象完全独立于侦听器对象.但这并不意味着您应该始终使用弱事件模式.这也不意味着您应该停止关心在您的应用程序中处理订阅.

                  There are certainly certain scenarios where you should use the weak event pattern. One such scenario is the data binding in WPF where a source object is completely independent of the listener object. But this doesn't mean that you should always use the weak event pattern. And it also doesn't mean that you should stop caring about disposing subscriptions in your applications.

                  这篇关于将所有标准事件处理程序替换为 WeakEventManager 或其变体是否安全?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持跟版网!

                    <tbody id='yQSR2'></tbody>
                    <bdo id='yQSR2'></bdo><ul id='yQSR2'></ul>

                    <legend id='yQSR2'><style id='yQSR2'><dir id='yQSR2'><q id='yQSR2'></q></dir></style></legend>

                      1. <tfoot id='yQSR2'></tfoot>
                        • <i id='yQSR2'><tr id='yQSR2'><dt id='yQSR2'><q id='yQSR2'><span id='yQSR2'><b id='yQSR2'><form id='yQSR2'><ins id='yQSR2'></ins><ul id='yQSR2'></ul><sub id='yQSR2'></sub></form><legend id='yQSR2'></legend><bdo id='yQSR2'><pre id='yQSR2'><center id='yQSR2'></center></pre></bdo></b><th id='yQSR2'></th></span></q></dt></tr></i><div id='yQSR2'><tfoot id='yQSR2'></tfoot><dl id='yQSR2'><fieldset id='yQSR2'></fieldset></dl></div>
                        • <small id='yQSR2'></small><noframes id='yQSR2'>