C# 事件取消订阅/重新订阅内存泄漏避免

C# 事件取消订阅/重新订阅内存泄漏避免,c#,.net,memory-leaks,C#,.net,Memory Leaks,我在我们的代码库中看到很多类似的代码: void Method() { this.someObject.SomeEvent -= someHandler; this.someObject.SomeEvent += someHandler; //... other stuff } 这在任何方面都有用吗? 我一直在怀疑实施者,认为我可能错过了一些东西 如果代码类似于: void Method() { this.someObject.SomeEvent -=

我在我们的代码库中看到很多类似的代码:

void Method()
{
     this.someObject.SomeEvent -= someHandler;
     this.someObject.SomeEvent += someHandler;
     //... other stuff
}
这在任何方面都有用吗? 我一直在怀疑实施者,认为我可能错过了一些东西

如果代码类似于:

void Method()
{
     this.someObject.SomeEvent -= someHandler;
     this.someObject = new WhateverClass();
     this.someObject.SomeEvent += someHandler;
     //... other stuff
}

第一个示例是试图停止可能导致问题(和泄漏)的多个订阅的良性尝试,第二个示例是试图停止内存泄漏

然而,您可以使用这样一种模式,它有它的好处,它不是阻止泄漏的防弹方法(即我只是帮助进行减法运算,没有多个订阅,并且您没有多次订阅),但它否定了正在进行的整个加/减操作

private EventHandler _stuff;

public event EventHandler Stuff
{
   add
   {
      if (_stuff== null || !_stuff.GetInvocationList().Contains(value))
         _stuff+= value;
   }
   // ignore the resharper warning
   remove => _stuff -= value;
}
尽管事实是,如果你想使用事件模式,你应该很清楚什么时候需要订阅和取消订阅,如果你不需要,你会有更大的问题


就个人而言,我更喜欢解耦的消息/事件聚合器(pub/sub类型的东西)。现在我很少有意识地创建事件管道

第一个示例是试图停止多个订阅,这可能会导致问题(和泄漏),第二个示例是试图停止内存泄漏

然而,您可以使用这样一种模式,它有它的好处,它不是阻止泄漏的防弹方法(即我只是帮助进行减法运算,没有多个订阅,并且您没有多次订阅),但它否定了正在进行的整个加/减操作

private EventHandler _stuff;

public event EventHandler Stuff
{
   add
   {
      if (_stuff== null || !_stuff.GetInvocationList().Contains(value))
         _stuff+= value;
   }
   // ignore the resharper warning
   remove => _stuff -= value;
}
尽管事实是,如果你想使用事件模式,你应该很清楚什么时候需要订阅和取消订阅,如果你不需要,你会有更大的问题


就个人而言,我更喜欢解耦的消息/事件聚合器(pub/sub类型的东西)。现在我很少有意识地创建事件管道

第一种方法仅在您希望声明没有绑定到同一事件的重复订阅时有效。如果在算法中多次调用Method(),并且只添加了someHandler,而从未从订阅服务器中删除,那么将多次调用someHandler回调。这是唯一的风险

关于内存泄漏,你的推理是完美的。本文将解释内存泄漏主题。


祝您度过愉快的一天

第一种方法仅在您希望声明没有绑定到同一事件的重复订阅时有效。如果在算法中多次调用Method(),并且只添加了someHandler,而从未从订阅服务器中删除,那么将多次调用someHandler回调。这是唯一的风险

关于内存泄漏,你的推理是完美的。本文将解释内存泄漏主题。


祝你度过一个愉快的日子

如果你遇到了这样的问题,你可能想考虑Soal.Actudio——请看一个简单的用法。若要终止或删除订阅,您需要将其丢弃,这样可以更容易地避免内存泄漏。你也可以把一堆可丢弃的东西扔进一个可组合的一次性文件中,并删除一行代码中的许多订阅。如果你遇到这样的问题,你可能想考虑Sytal.Actudio——请看一个简单的用法。若要终止或删除订阅,您需要将其丢弃,这样可以更容易地避免内存泄漏。您还可以将一堆一次性物品放入CompositeDisposable中,并在一行代码中删除多个订阅。