c# - 我必须删除处理程序吗

标签 c# .net events eventhandler

随着我对 C# 和 GC 的深入研究,我发现越来越多的事情我不太确定。我一直认为只有在我的类中有一些非托管资源时才需要 Dispose 和相应的 Finalizer。

但我有很多情况只有原生 C# 类,我不太清楚是否需要 Dispose 和相应的终结器。例如,当我将事件处理程序附加到我的事件时。

调用 Dispose 时是否需要删除事件处理程序?另外有人告诉我,如果事件处理程序仍然附加,则该对象可能不会被收集。如果是这种情况,则 GC 会以某种方式受到损害。

是否可以总结一下何时以及如何实现 Dispose 和 Finalizer?

事实上我对此有更多疑问,但也许对这个问题的回答可以帮助我进一步。

最佳答案

要弄清您关于何时进行 Dispose 和 Finalize 的一般性问题:

如果您的类(class)中有一个字段是 IntPtr (或一些其他类型的非托管资源,但 IntPtr 是最常见的)并且您的类有责任清理该资源,然后您需要实现终结器。在该终结器中,您也应该释放 IntPtr 指向的任何资源。如果您没有 IntPtr,那么您持有的类应该处理自己的终结并实现 IDisposeable(请参阅下一部分)

如果你的类中有一个字段实现了IDisposable并且您的类负责在该对象之后清理您的类还应该实现 IDisposable 并且在该 dispose 方法中您应该对该对象调用 Dispose()

对于事件处理程序,这是个人喜好的问题。你可以,但只有你做与不做才重要if the person who subscribed to the event messed up their code .

Unless you expect the publisher of the event to outlive the subscriber, there's no reason to remove the event handler...

我个人不这样做,但我认识一些这样做的人。如果您想这样做,该过程只需在您的 dispose 方法中将事件处理程序设置为 null

public sealed class Example : IDisposable 
{
    public EventHandler MyEvent;

    public void Dispose()
    {
        MyEvent = null;
    }
}

编辑:很好的一点是Hans Passant brought up in the comments : 你永远不需要终结器,如果你有一个需要终结器的非托管资源,它应该被包裹在 SafeHandle 中。包装器为您处理最终确定。一旦你这样做了,对象就变成了另一个普通的 IDisposable,你需要在你的 .Dispose() 方法中处理。

关于c# - 我必须删除处理程序吗,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29084266/

相关文章:

c# - 以反射方式将一个事件直接连接到另一个事件

c# - 是否有 .Net API 无需轮询即可检测 Windows 服务的状态更改?

c# - 用测试数据填充 SQL Server 表

c# - InRequestScope 中的 Ninject 依赖项不会被释放

c# - 如何将这些 LINQ 结果加载到我的 ViewModel 类中?

javascript - Asp.net MVC 3.0 中的 JQuery 模式和最佳实践

c# - .net 4.0 和 .net 4.0.3 有什么区别?

c# - 如何在javascript中访问动态创建的对象?

.net - Raspbian 操作系统(Linux 和 Mono)上的 VB.net

wpf - WPF DataGrid DataBindingComplete 事件在哪里?