MTR*_*MTR 13 c# events garbage-collection destructor
我认为这是一个C#初学者问题,但我似乎无法找到正确的解决方案.
我有一个ClassOne对象,它定义了一个事件.我创建了一个ClassTwo对象,它被认为是一个黑盒子,这意味着我不知道它是否会注册到任何事件.ClassTwo构造函数注册到ClassOne的事件.当ClassTwo对象超出范围时,问题就出现了.垃圾收集器永远不会删除此对象,因为它从未取消注册该事件.
所以我有两个问题:
当ClassTwo对象超出范围时,有没有办法知道?对于一个旧的C++程序员来说,这将是在析构函数中,但是使用C#这不起作用.
有没有一个调试工具可以帮助我找到这样的对象?
以下是重现问题的示例代码:
public partial class MainWindow : Window
{
static public ClassOne classOne = new ClassOne();
public MainWindow()
{
InitializeComponent();
ClassTwo classtwo = new ClassTwo();
}
private void buttonTest_Click(object sender, RoutedEventArgs e)
{
GC.Collect();
}
}
public class ClassOne
{
public ClassOne()
{
Trace.WriteLine(this + " constructor");
}
~ClassOne()
{
Trace.WriteLine(this + " destructor");
}
public delegate void UpdateFunc(object sender, EventArgs args);
public event UpdateFunc OnUpdate;
}
public class ClassTwo
{
public ClassTwo()
{
Trace.WriteLine(this + " constructor");
MainWindow.classOne.OnUpdate += new ClassOne.UpdateFunc(classOne_OnUpdate);
}
void classOne_OnUpdate(object sender, EventArgs args)
{
throw new NotImplementedException();
}
~ClassTwo()
{
Trace.WriteLine(this + " destructor");
}
}
Run Code Online (Sandbox Code Playgroud)
我会IDisposable在这样的对象上实现并从Dispose方法中的事件中取消注册.你会像这样使用你的对象:
using(var two = new ClassTwo(classOne))
{
// Do something with two
}
// object can now be garbage collected.
Run Code Online (Sandbox Code Playgroud)
如果来电者没有打电话Dispose,那你就不走运了.
除非它实现并且调用者通过正确调用进行协作.(当然,为什么呼叫者不合作?)IDisposable Dispose
不是我的.:(我认为你最好的选择是实施IDisposable和取消注册Dispose.