Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/270.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
EventHandler和C#类析构函数/处置_C#_Winforms_Events_Delegates - Fatal编程技术网

EventHandler和C#类析构函数/处置

EventHandler和C#类析构函数/处置,c#,winforms,events,delegates,C#,Winforms,Events,Delegates,我对C#类及其解构器有点困惑 我必须在构造函数中得到的类实例中使用一些事件处理程序: public Foo(IFooHandler handler) { handler.Load += Load; handler.Close += Close; } 当Foo类被销毁时,我需要取消订阅该活动。我是在那里还是在解构器中实现IDisposable并取消订阅?我需要消耗这些事件,我不能用另一种方式 对于其中一个类,我创建一个实例,检查进度,然后该类实例超出范围。另一种情况是,

我对C#类及其解构器有点困惑

我必须在构造函数中得到的类实例中使用一些事件处理程序:

 public Foo(IFooHandler handler)
 {
     handler.Load += Load;
     handler.Close += Close;
 }
当Foo类被销毁时,我需要取消订阅该活动。我是在那里还是在解构器中实现IDisposable并取消订阅?我需要消耗这些事件,我不能用另一种方式

对于其中一个类,我创建一个实例,检查进度,然后该类实例超出范围。另一种情况是,它会一直停留在
main表单中
,直到表单关闭。第一个是我所担心的,因为它可能仍然有一个对该事件处理程序的引用,并且不能正常运行


我不想泄露内存。何时以及如何取消订阅?

不要在析构函数中执行此操作,因为在附加事件处理程序时不会调用它:当您将Foo的实例方法附加为Bar事件的处理程序时,Bar将保留对Foo的引用,因此不会对Foo进行垃圾收集,也不会调用其析构函数

您应该实现IDisposable,并显式地处理对象

public void Dispose()
{
    if (handler != null)
    {
        handler.Load -= Load;
        handler.Close -= Close;
    }
}

如果您曾经遇到过这样的问题:类A是一个长寿命的类,而类B是订阅类A事件的短命类,那么您可能会感兴趣。这可能是一个直到很晚才发现的问题,即

啊!我认为我们不应该实现IDisposable,除非我们正在清理非托管代码?IDisposable可以出于其他原因实现,它不仅限于清理非托管资源……如果您看看常见的一次性模式,就可以找到处理托管和非托管资源的路径。大多数情况下,您只有非托管资源和/或托管资源。但是对于你的情况来说,管理好的资源也没关系,这些资源应该被清理掉。为了完成Oliver的评论,这里有一个有用的链接:哈哈哈。与自动驾驶内存泄漏有很大联系。我正在处理一个项目中的静态事件处理程序,我想知道所有的麻烦是否值得。这个链接让我很开心。