清理事件处理程序 [英] Cleaning Up Event Handlers

查看:60
本文介绍了清理事件处理程序的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

你好,


我知道当创建一个EventHandler时,它会为对象创建一个引用

,因此阻止了GCing。 br />

因此,我一直在我的控件中实现IDisposable

清理混乱(改造不是一件有趣的事情)。


无论如何,我的问题是关于这个问题。当我创建控件时,.NET IDE会自动为我注册事件(组件

设计器生成的代码代码区域)。所以我注意到那里

类似于:

this.menuItemAudioFile.CheckedChanged + = new

System.EventHandler(this.menuItemAudioFile_Checked Changed);


我是否正确假设如果我动态创建包含

代码(例如theCtrl = new MyCtrl()不止一次)我需要 - =在

我的Dispose功能?如果是这样的话,为什么.NET IDE不会自动地为
- =在Dispose函数中它们?有没有理由这是完全由实施者完成的?


或者我可能完全误解了这个问题!


谢谢!

Hello,

I''m aware that when an EventHandler is created, it creates a reference
to the object, therefore preventing GCing.

Therefore, I''ve been implementing IDisposable in my controls to
cleanup the mess (not a fun thing to retrofit).

Anyway, my question is regarding this issue. When I create controls,
the .NET IDE automatically registers events for me (the "Component
Designer generated code" region of code). So I notice in there
something like:
this.menuItemAudioFile.CheckedChanged += new
System.EventHandler(this.menuItemAudioFile_Checked Changed);

Am I correct in assuming that if I dynamically create the containing
code (e.g. theCtrl = new MyCtrl() more than once) I need to -= that in
my Dispose function? If that''s the case, why doesn''t the .NET IDE
automatically -= them in a Dispose function? Is there a reason this is
completely left up to the implementor?

Or maybe I''m totally misunderstanding the issue!

Thanks!

推荐答案

如果您显示,您附加到CheckChanged事件的位置,

这没关系,因为它是一个循环引用,GC将选择

up。表单中包含对控件的引用,该控件通过事件间接引用

格式。


唯一需要担心的时间这是当你在另一个班级上订阅

的活动时,你不希望这个参考文件阻止你处置你自己。


这是一个很好的例子,当你有一个表格附加到

另一个表格'的已结事件。如果订阅

事件的表单关闭,则该对象仍然在内存中(虽然Disposed)因为

在另一个表单上订阅Closed事件。


但是,如果所有的事件和订阅都是自包含的,那么在

意义上它们都在同一个表单/控件上,并且仅限于彼此,

然后你不必担心这个。这是当你的表格订阅

之外的事件(或任何课程,而不仅仅是形式)

,你必须担心。 />
-

- Nicholas Paldino [.NET / C#MVP]

- mv*@spam.guard.caspershouse.com

" dmeglio" < dm ***** @ gmail.com写信息

news:11 ********************* @ q66g2000hsg.googlegro ups.com ...
In the case that you show, where you attach to the CheckChanged event,
it doesn''t matter, because it is a circular reference, which GC will pick
up. The form holds a reference to the control, which holds a reference to
the form indirectly through the event.

The only time that you have to worry about this is when you subscribe to
an event on another class, and you don''t want that reference to prevent you
from disposing yourself.

A good example of this is when you have a form that is attached to
another form''s Closed event. If the the form that is subscribed to the
event closes, the object is still in memory (although Disposed) because of
the subscription to the Closed event on the other form.

However, if all the events and subscriptions are self-contained, in the
sense that they are all on the same form/control and only to each other,
then you don''t have to worry about this. It''s when your form subscribes to
an event outside of itself (or any class, not just forms for that matter)
that you have to worry.
--
- Nicholas Paldino [.NET/C# MVP]
- mv*@spam.guard.caspershouse.com

"dmeglio" <dm*****@gmail.comwrote in message
news:11*********************@q66g2000hsg.googlegro ups.com...

你好,


我知道当创建一个EventHandler时,它会创建对象的引用

,因此阻止了GCing。


因此,我一直在我的控件中实现IDisposable

清理混乱(改造不是一件有趣的事情)。


无论如何,我的问题是关于这个问题。当我创建控件时,.NET IDE会自动为我注册事件(组件

设计器生成的代码代码区域)。所以我注意到那里

类似于:

this.menuItemAudioFile.CheckedChanged + = new

System.EventHandler(this.menuItemAudioFile_Checked Changed);


我是否正确假设如果我动态创建包含

代码(例如theCtrl = new MyCtrl()不止一次)我需要 - =在

我的Dispose功能?如果是这样的话,为什么.NET IDE不会自动地为
- =在Dispose函数中它们?有没有理由这是完全由实施者完成的?


或者我可能完全误解了这个问题!


谢谢!
Hello,

I''m aware that when an EventHandler is created, it creates a reference
to the object, therefore preventing GCing.

Therefore, I''ve been implementing IDisposable in my controls to
cleanup the mess (not a fun thing to retrofit).

Anyway, my question is regarding this issue. When I create controls,
the .NET IDE automatically registers events for me (the "Component
Designer generated code" region of code). So I notice in there
something like:
this.menuItemAudioFile.CheckedChanged += new
System.EventHandler(this.menuItemAudioFile_Checked Changed);

Am I correct in assuming that if I dynamically create the containing
code (e.g. theCtrl = new MyCtrl() more than once) I need to -= that in
my Dispose function? If that''s the case, why doesn''t the .NET IDE
automatically -= them in a Dispose function? Is there a reason this is
completely left up to the implementor?

Or maybe I''m totally misunderstanding the issue!

Thanks!



6月1日下午1:15,Nicholas Paldino [.NET / C#MVP ]

< m ... @ spam.guard.caspershouse.comwrote:
On Jun 1, 1:15 pm, "Nicholas Paldino [.NET/C# MVP]"
<m...@spam.guard.caspershouse.comwrote:

如果您显示,其中你附加到CheckChanged事件,

它没关系,因为它是一个循环引用,GC将选择

up。表单中包含对控件的引用,该控件通过事件间接引用

格式。


唯一需要担心的时间这是当你在另一个班级上订阅

的活动时,你不希望这个参考文件阻止你处置你自己。


这是一个很好的例子,当你有一个表格附加到

另一个表格'的已结事件。如果订阅

事件的表单关闭,则该对象仍然在内存中(虽然Disposed)因为

在另一个表单上订阅Closed事件。


但是,如果所有的事件和订阅都是自包含的,那么在

意义上它们都在同一个表单/控件上,并且仅限于彼此,

然后你不必担心这个。这是当你的表格订阅

之外的事件(或任何课程,而不仅仅是形式)

,你必须担心。 />

-

- Nicholas Paldino [.NET / C#MVP]

- m ... @ spam.guard.caspershouse。 com


" dmeglio" < dmeg ... @ gmail.com写信息


新闻:11 ********************* @ q66g2000hsg .googlegro ups.com ...
In the case that you show, where you attach to the CheckChanged event,
it doesn''t matter, because it is a circular reference, which GC will pick
up. The form holds a reference to the control, which holds a reference to
the form indirectly through the event.

The only time that you have to worry about this is when you subscribe to
an event on another class, and you don''t want that reference to prevent you
from disposing yourself.

A good example of this is when you have a form that is attached to
another form''s Closed event. If the the form that is subscribed to the
event closes, the object is still in memory (although Disposed) because of
the subscription to the Closed event on the other form.

However, if all the events and subscriptions are self-contained, in the
sense that they are all on the same form/control and only to each other,
then you don''t have to worry about this. It''s when your form subscribes to
an event outside of itself (or any class, not just forms for that matter)
that you have to worry.

--
- Nicholas Paldino [.NET/C# MVP]
- m...@spam.guard.caspershouse.com

"dmeglio" <dmeg...@gmail.comwrote in message

news:11*********************@q66g2000hsg.googlegro ups.com...

你好,
Hello,


我是意识到当创建EventHandler时,它会为对象创建一个引用

,从而阻止GCing。
I''m aware that when an EventHandler is created, it creates a reference
to the object, therefore preventing GCing.


因此,我一直在我的控件中实现IDisposable

清理混乱(不是一件有趣的事情改造)。
Therefore, I''ve been implementing IDisposable in my controls to
cleanup the mess (not a fun thing to retrofit).


无论如何,我的问题是关于这个问题。当我创建控件时,.NET IDE会自动为我注册事件(组件

设计器生成的代码代码区域)。所以我注意到那里

类似于:

this.menuItemAudioFile.CheckedChanged + = new

System.EventHandler(this.menuItemAudioFile_Checked Changed);
Anyway, my question is regarding this issue. When I create controls,
the .NET IDE automatically registers events for me (the "Component
Designer generated code" region of code). So I notice in there
something like:
this.menuItemAudioFile.CheckedChanged += new
System.EventHandler(this.menuItemAudioFile_Checked Changed);


我是否正确假设如果我动态创建包含

代码(例如theCtrl = new MyCtrl()更多不止一次)我需要 - =

我的Dispose函数?如果是这样的话,为什么.NET IDE不会自动地为
- =在Dispose函数中它们?有没有理由这完全由实施者承担?

Am I correct in assuming that if I dynamically create the containing
code (e.g. theCtrl = new MyCtrl() more than once) I need to -= that in
my Dispose function? If that''s the case, why doesn''t the .NET IDE
automatically -= them in a Dispose function? Is there a reason this is
completely left up to the implementor?


或许我完全误解了这个问题!
Or maybe I''m totally misunderstanding the issue!


谢谢! - 隐藏引用的文字 -
Thanks!- Hide quoted text -



- 显示引用的文字 -


- Show quoted text -



从本质上讲,如果一个对象订阅了其中一个孩子的事件(例如一个封装的对象),我就是''好吗?

So essentially, if an object subscribes to an event of one of it''s
children (e.g. an encapsulated object), I''m ok?


星期五,2007年6月1日09:36:19 -0700,dmeglio< dm ***** @ gmail.comwrote:
On Fri, 01 Jun 2007 09:36:19 -0700, dmeglio <dm*****@gmail.comwrote:

我知道当创建一个EventHandler时,它会为对象创建一个引用

,从而阻止了GCing。 />

因此,我一直在我的控件中实现IDisposable

清理混乱(改造不是一件有趣的事情)。
I''m aware that when an EventHandler is created, it creates a reference
to the object, therefore preventing GCing.

Therefore, I''ve been implementing IDisposable in my controls to
cleanup the mess (not a fun thing to retrofit).



我认为你做的事情你不需要做。见下文。

I think you''re doing something you don''t need to do. See below.


无论如何,我的问题是关于这个问题。当我创建控件时,.NET IDE会自动为我注册事件(组件

设计器生成的代码代码区域)。所以我注意到那里

类似于:

this.menuItemAudioFile.CheckedChanged + = new

System.EventHandler(this.menuItemAudioFile_Checked Changed);


我是否正确假设如果我动态创建包含

代码(例如theCtrl = new MyCtrl()不止一次)我需要 - =在

我的Dispose功能?如果是这样的话,为什么.NET IDE不会自动地为
- =在Dispose函数中它们?有没有理由这完全由实施者承担?

Anyway, my question is regarding this issue. When I create controls,
the .NET IDE automatically registers events for me (the "Component
Designer generated code" region of code). So I notice in there
something like:
this.menuItemAudioFile.CheckedChanged += new
System.EventHandler(this.menuItemAudioFile_Checked Changed);

Am I correct in assuming that if I dynamically create the containing
code (e.g. theCtrl = new MyCtrl() more than once) I need to -= that in
my Dispose function? If that''s the case, why doesn''t the .NET IDE
automatically -= them in a Dispose function? Is there a reason this is
completely left up to the implementor?



如果无法收集包含该事件的类,则无法收集已订阅该事件的任何其他类

。这确实意味着

,如果你有一个课程'订阅了一个活动但没有

取消订阅你试图摆脱它(你没有其他明确的

引用它),该类不会被收集。但是,如果发生这种情况

然后带有事件的类也没有被引用,那么带有事件的类或订阅其事件的类都不会

可以到达,因此两者都可以在那时收集。


现在,所有这些都说,在您的特定示例中,您似乎正在处理

,其代码中包含带事件的实例的类是

,其中包含处理程序。所以大概你不会丢弃这个类,直到你还丢弃了事件的实例,然后

然后一切都得到了清理。


这是设计师创建的表单和控件的情况,这是

为什么没有必要做任何类型的IDispose东西来清理事情了。

事实上,我不能想到任何与事件订阅有关的情况

,这需要你实现一个Dispose方法。事件是管理,订阅者管理,所以GC知道所有关于他们和

应该总是做正确的事情。


Pete

If the class containing the event cannot be collected then any other class
that has subscribed to the event also cannot be collected. This does mean
that if you''ve got a class that''s subscribed to an event but does not
unsubscribe before you try to get rid of it (you have no other explicit
references to it), the class won''t be collected. However, if that happens
and then the class with the event is also left unreferenced, then neither
the class with the event or the class subscribed to its event will be
reachable and so both can be collected at that point.

Now, all that said, in your particular example you appear to be dealing
with code in which the class containing the instance with the event is the
one with the handler. So presumably you''re not going to be discarding
that class until you''ve also discarded the instance with the event, and
then everything gets cleaned up fine.

This is the situation with Designer-created forms and controls, which is
why there''s no need to do any sort of IDispose stuff to clean things up.
In fact, I can''t think of any situation related to event subscription
which would require you to implement a Dispose method. Events are
managed, subscribers are managed, so the GC knows all about them and
should always do the right thing.

Pete


这篇关于清理事件处理程序的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆