VB.Net 集合中对象的生命周期

发布于 2024-10-02 08:00:41 字数 616 浏览 7 评论 0原文

我试图在下面的代码中找出 tmpTabPages 的生命周期。假设表单有一个名为 MyTabControl 的空 TabControl,并且有一个名为 NameCollection 的字符串集合。

Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
    For Each itm In NameCollection
        Dim tmpTabPage as New TabPage(itm.toString)

        'Add Controls to tmpTabPage

        MyTabControl.TabPages.Add(tmpTabPage)
    Next
End Sub

由于 tmpTabPage 的范围是 For/Next 块,因此它的生命周期通常是直到该块的末尾,对吗?但是,由于它被添加到范围在块之外的集合中,因此它是否具有与集合(或者在本例中为 MyTabControl)相同的生命周期?最后,如果我调用 MyTabControl.TabPages.Clear 集合中的 tmpTabPages 是否会被销毁,或者它们只会占用内存?

I'm trying to figure out the lifetime of the tmpTabPages in the following bit of code. Lets assume the form has an empty TabControl named MyTabControl, that there's a collection of strings called NameCollection.

Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
    For Each itm In NameCollection
        Dim tmpTabPage as New TabPage(itm.toString)

        'Add Controls to tmpTabPage

        MyTabControl.TabPages.Add(tmpTabPage)
    Next
End Sub

Since the scope of the tmpTabPage is the For/Next block, typically it's lifetime would be until the end of the block right? But since it is added to a collection that has a scope outside of the block does it get the same lifetime as the collection, or in this case the MyTabControl? Finally, if I call MyTabControl.TabPages.Clear will the tmpTabPages in the collection be destroyed or will they just sit around taking up memory?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

日记撕了你也走了 2024-10-09 08:00:41

从 Control 派生的类(包括 TabPage)最重要的是 Dispose() 方法。它们不受自动垃圾收集的影响,Winforms 保留一个内部表,将控件的句柄映射到控件引用。这就是为什么你的主窗体不会突然被垃圾收集,即使你的程序没有保留对它的引用。

将 TabPage 添加到 TabControl 的集合中会负责自动处理。这同样适用于 TabControl,它将添加到表单的 Controls 集合中。正常的事件链是您的程序或用户关闭表单。 Form 类迭代其子控件并调用其 Dispose() 方法。 TabControl 在其 Dispose() 方法中执行相同的操作,处理选项卡页。 Windows 窗口在此过程中被销毁,从该映射表中删除句柄,现在允许垃圾收集器最终收集控件的托管包装器。

有一个令人讨厌的陷阱给许多 Winforms 程序员带来了麻烦。如果您从其父级集合中删除控件,则您有责任自行处置它。删除它不会自动处置它。 Winforms 通过暂时将控件重新设置为名为“停车窗口”的隐藏窗口来保持本机窗口处于活动状态。很好的功能,它允许您将控件从一个父级移动到另一个父级,而无需销毁并重新创建该控件。

但这里的关键词是“暂时”。如果您下次重新设置控件的父级,这只是暂时的。因此它从停车窗口移至新的父窗口。如果你不真正重新调整它的父级,那么它就会永远在停车窗上保持活力。吞噬资源直到程序终止。这也称为泄漏。如果您已经创建了 10,000 个窗口,而 Windows 拒绝创建另一个窗口,则可能会使您的程序崩溃。

ControlCollection.Clear() 方法在这里尤其有害。它不会处理控件,它们都被移动到那个停车窗口。如果这不是有意的(很少是这样),您必须自己对它们调用 Dispose()。

The big deal about classes derived from Control (including TabPage) is the Dispose() method. They are immune from automatic garbage collection, Winforms keeps an internal table that maps the Handle of a control to the control reference. That's why, say, your main form doesn't suddenly get garbage collected, even though your program doesn't keep a reference to it.

Adding the TabPage to the TabControl's collection takes care of automatic disposal. The same applies for the TabControl, it would be added to the form's Controls collection. The normal chain of events is that either your program or the user closes the form. The Form class iterates its child controls and calls their Dispose() method. TabControl does the same thing in its Dispose() method, disposing the tab pages. The Windows window gets destroyed in the process, removing the Handle from that mapping table and now allowing the garbage collector to, eventually, collect the managed wrapper for the controls.

There is a nasty trap that gets many Winforms programmers in trouble. If you remove a control from its parent's collection then you get the responsibility of disposing it yourself. Removing it does not automatically dispose it. Winforms keeps the native window alive by temporarily re-parenting the control to a hidden window named the "parking window". Nice feature, it allows you to move a control from one parent to another without having to destroy and re-create the control.

But the keyword there is "temporarily". It is only temporarily if you next reparent the control. So it gets moved from the parking window to the new parent. If you don't actually reparent it then it will stay alive for ever on the parking window. Gobbling up resources until the program terminates. This is otherwise known as a leak. It can crash your program when Windows refuses to create another window when you've already created 10,000 of them.

The ControlCollection.Clear() method is especially harmful here. It does not dispose the controls, they all get moved to that parking window. If that's not intended, it rarely is, you'll have to call Dispose() on them yourself.

玩物 2024-10-09 08:00:41

当无法获取 .NET 中的对象时,它们就符合垃圾回收的条件。在这种情况下,有一种通过 TabPages 集合访问 TabPage 的方法,直到它从集合或选项卡中删除控件本身就有资格被收集。

现在,当一个对象符合垃圾收集条件时,这并不意味着它会立即被垃圾收集 - 垃圾收集根据一些相当复杂的启发式方法在不同时间运行,并且还有“几代”内存,这使得事情更难以预测。

但基本上:

  • 您不需要担心添加到集合中的对象会被神秘地收集并导致问题
  • 您通常不需要担心对象会永远泄漏内存。当然,在某些情况下,您确实需要采取一些积极的步骤来确保当您不再使用某个对象时该对象符合收集条件,但它们相对 > 罕见。 (根据我的经验,它们通常与静态变量和/或事件相关。)

Objects in .NET become eligible for garbage collection when there's no way of getting at them. In this case, there will be a way of getting at the TabPage via the TabPages collection, until either it's removed from the collection or the tab control itself becomes eligible for collection.

Now when an object becomes eligible for garbage collection, that doesn't mean it's garbage collected straight away - the garbage collection runs at various times according to some fairly complex heuristics, and there are also "generations" of memory which make things harder to predict.

But basically:

  • You don't need to worry that an object that's been added to a collection will be mysteriously collected and cause problems
  • You generally don't need to worry that objects will leak memory forever. There are certainly situations where you do need to take some active steps to make sure that an object is eligible for collection when you're no longer using it, but they're relatively rare. (Typically they are related to static variables and/or events, in my experience.)
诺曦 2024-10-09 08:00:41

因为某些东西引用了它们不会被处理的控件。

是的,如果您不向集合中添加对它们的引用,则生命周期将持续到过程结束。

清除将从集合中删除对象,并且如果没有其他对它们的引用(不应该出现在您描述的情况下),它们将被垃圾收集

because soemthing has a reference to the controls they will not be disposed of.

yes the lifetime would be till the end of the procedure if you were not adding a reference to them to the colelction.

the clear will remove the objects from the collection and they will get garbage collected provided there are no other references to them (which there shuoldnt be in the situation you describe)

翻了热茶 2024-10-09 08:00:41

您仅将 TabPage 对象的引用添加到集合中,而不是对象 TmpTabPage。在本例中,tmpTabPage 对象仅用于分配内存。

You add only a reference of the TabPage object to the collection not the object TmpTabPage. The tmpTabPage object in this case you use it only for allocating memory.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文