C# 处理它引用的对象后,事件会发生什么情况?
如果将某个对象的方法链接到委托,然后处置该对象,会发生什么情况 像这样:C# 处理它引用的对象后,事件会发生什么情况?,c#,events,delegates,C#,Events,Delegates,如果将某个对象的方法链接到委托,然后处置该对象,会发生什么情况 像这样: class Hunter { public event Action Shoot; public execute() { Form formBabySeal = new Form(); Shoot += formBabySeal.Close; formBabySeal.Show(); formBabySeal.Close(); /
class Hunter
{
public event Action Shoot;
public execute()
{
Form formBabySeal = new Form();
Shoot += formBabySeal.Close;
formBabySeal.Show();
formBabySeal.Close(); //Dispose Form
if (Shoot != null)
{
Shoot(); //event is null?
}
}
}
带有SOS扩展的WinDBG有一种显示任何对象根目录的方法。这可能会给您提供更多线索。带有SOS扩展的WinDBG有一种方法可以显示任何对象的根目录。这可能会给您提供更多线索。
formBabySeal
不是因为您处理了它而为null
。因此,将调用formBabySeal.Close()
在查看调用的方法时,您的代码与此等效:
Form formBabySeal = new Form();
formBabySeal.Show();
formBabySeal.Close(); //Dispose Form
formBabySeal.Close();
这将关闭表单(第一次调用close
),第二次调用不会执行任何操作,因为表单已经关闭
但是,正如Steve在评论部分指出的,您的代码将引入内存泄漏,因为
Shoot
仍然保留对formBabySeal
的Close
方法的引用,并且由于此formBabySeal
将保持活动状态,只要类Hunter
的实例处于活动状态。formBabySeal
不是null
,只是因为您处理了它。因此,将调用formBabySeal.Close()
在查看调用的方法时,您的代码与此等效:
Form formBabySeal = new Form();
formBabySeal.Show();
formBabySeal.Close(); //Dispose Form
formBabySeal.Close();
这将关闭表单(第一次调用close
),第二次调用不会执行任何操作,因为表单已经关闭
但是,正如Steve在评论部分所指出的,您的代码将引入内存泄漏,因为
Shoot
仍然引用formBabySeal
的Close
方法,因此只要类Hunter
的实例处于活动状态,formBabySeal
将保持活动状态。Yes。Shoot不是空的,但它不做任何事情either@hcb你认为它应该做什么?表单已经关闭!还有,请看我的答案。Shoot不是空的,但它不做任何事情either@hcb你认为它应该做什么?表单已经关闭!另外,请参阅我的答案。我想补充一点,这是导致内存泄漏的常见方式,因为尽管对象已被释放,但它仍然被应用程序引用,因此GC不会收集它。文档指定了引发异常的不同场景。“条件:当WindowsState设置为最大化时,您无法从激活的事件调用此方法。”嗯,我一直在尝试您的代码(第一个代码块)当窗体被释放时,Close函数似乎不会抛出异常。这意味着窗体不是真的被释放,或者Close函数自己处理它,这很奇怪,因为它应该被释放。steven的评论回答了这一点。谢谢allAnd,我想补充一点,这是引入内存泄漏的一种常见方式尽管对象已被释放,但它仍然被应用程序引用,因此GC不会收集。文档指定了引发异常的不同场景。“条件:当WindowsState设置为最大化时,您无法从激活的事件调用此方法。”嗯,我一直在尝试您的代码(第一个代码块)并且当表单被释放时,关闭函数似乎不会抛出异常。这意味着要么表单没有真正被释放,要么关闭函数自己处理它,这很奇怪,因为它应该被释放。steven的评论回答了这个问题。谢谢大家