Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/259.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

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/asp.net/36.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
C# 在发布服务器和订阅服务器都持有相互引用的情况下删除析构函数中的事件处理程序_C#_Asp.net_Events_Memory Leaks_Event Handling - Fatal编程技术网

C# 在发布服务器和订阅服务器都持有相互引用的情况下删除析构函数中的事件处理程序

C# 在发布服务器和订阅服务器都持有相互引用的情况下删除析构函数中的事件处理程序,c#,asp.net,events,memory-leaks,event-handling,C#,Asp.net,Events,Memory Leaks,Event Handling,假设我们有以下模型: public class Bar<T>:List<T> { public delegate void CollectionChangedDelegate(); public event CollectionChangedDelegate CollectionChanged; } public class Foo { Bar<object> MyCol

假设我们有以下模型:

    public class Bar<T>:List<T>
    {
        public delegate void CollectionChangedDelegate();
        public event CollectionChangedDelegate CollectionChanged;
    }

    public class Foo
    {
        Bar<object> MyCollection = new Bar<object>();

        public Foo()
        {
            MyCollection.CollectionChanged += new Bar<object>.CollectionChangedDelegate(MyCollection_CollectionChanged);
        }

        public void MyCollection_CollectionChanged()
        {
            //Do Something
        }

        ~Foo() //Would this work ?
        {
            MyCollection.CollectionChanged -= MyCollection_CollectionChanged;
        }
    }
公共类栏:列表
{
public delegate void collectionchangedelegate();
公共事件集合更改Legate集合更改;
}
公开课Foo
{
Bar MyCollection=新的Bar();
公共食物(
{
MyCollection.CollectionChanged+=新条。CollectionChangedDelegate(MyCollection\u CollectionChanged);
}
public void MyCollection\u CollectionChanged()
{
//做点什么
}
~Foo()//这样行吗?
{
MyCollection.CollectionChanged-=MyCollection\u CollectionChanged;
}
}

在这种情况下可以调用类
Foo
的析构函数吗?

这样做是没有意义的。让我们假设有这样一个订阅。现在,要让我们使用
~Foo
方法,我们必须被收集,所以我们必须是无法访问的。由于事件的工作方式,订阅使我们可以访问(发布者有对订阅者的引用),因此我们可以推断
MyCollection
也无法访问。如果不是,我们就不会被收留

如果无法访问
MyCollection
,则表示它已经被收集,或者即将被收集。没有必要取消订阅

删除
~Foo
:它在这里毫无意义;实际上,它比无意义更糟糕——除了没有任何有用的用途之外,它还强制垃圾收集器将该对象推送通过一个额外的步骤(终结器队列)


然而,您可能希望添加某种确定性清理,以实现这一点;正如Joroen所指出的,
IDisposable
可能有用-但是,如果不了解更多的上下文,很难说它是否适合这种情况。

首先,我相信您正在尝试编写ObservableCollection
您可以在此处找到信息:

现在,如果我的对象包含需要处置的数据成员,我将实现IDisposable并在那里处置它们,或者至少删除事件订阅。
这样暗示:

class Foo:Idisposable 
{
    public void Dispose(bool b)
    {
         MyCollection.CollectionChanged -= MyCollection_CollectionChanged;
    }
}

您不应该使用析构函数,而应该使用IDisposable接口。回答你的问题:如果没有其他生物持有对Foo类的引用,它们都将被收集,请参阅:好的,简单点。。Foo将被收集,无论什么权利?那就不需要析构函数了?你说我的收集是不可能的,我怎么能保证呢?假设我创建了Foo的实例,因此也将创建Bar的实例(MyCollection),我如何保证在范围结束时收集MyCollection并使其不可访问?也就是说,Foo类代表我正在处理的系统中的一个业务实体,并且在任何地方都被充分使用(这就是为什么IDisposable不是一个选项)。我正在试图找出它是否可能是内存泄漏的原因?我们团队中的一名开发人员声称是,他添加了析构函数,并测试了其清理内存的效果。我想确定that@SirajMansour我说的是调用
~Foo
的场景:要实现这一点,我们可以假设集合不可访问(否则我们就无法访问)。至于保持集合不可访问-目前它是一个私有字段-唯一能知道它的是
Foo
实例。基于显示的代码(仅显示的代码),我再说一遍:
~Foo
比无用更糟糕。它没有好的效果,也有明确的负面影响。还有一个问题?如果不是编写析构函数,这种模式会导致内存泄漏吗?如果是这样的话?考虑到Foo是系统中无处不在的商业实体。@SirajMansour不是,不是在代码中own;再次—在代码运行的场景中,我们已经知道对象和集合都是不可访问的。它没有任何用途。我不想写它,实际上它已经写了,我正在处理内存泄漏。我想知道这是否会导致内存泄漏,因为类Foo代表一个业务我工作的系统中的实体,在任何地方都被彻底使用。