【问题标题】:What happens to memory, when the Tab removes itself from Items collection?当 Tab 从 Items 集合中删除时,内存会发生什么?
【发布时间】:2019-04-10 13:19:56
【问题描述】:

我将在这个问题中使用伪代码,所以请在理论上参考这个(我的意思是,会有一些简化)

假设这种情况:

我的应用程序有 MainWindow,其中有 TabControl。为了从其集合中删除项目,我使用 MainWindowstatic 函数如下:

public static void CloseTab(string someKindOfTabIdentity)
{
    var tab = myTabControl.Items.FirstOfDefault(someScenario);
    if (tab != null)
    {
        myTabControl.Items.Remove(tab);
        tab.Content = null;
        tab = null;
        GC.Collect();
    }
}

现在,我有 Page1,我允许用户通过某些功能关闭标签页

private void GoToPage2()
{
    MainWindow.CreatePage2AddToTabControlAndNavigateToIt()
    MainWindow.CloseTab(myCurrentPage1Tab);
    App.Cursor = Cursors.Arrow;
}

这个函数应该创建一个新的Tab,给它分配内容,然后使用MainWindow.CloseTab(myCurrentPage1Tab);,关闭当前的Tab,它包含Page1

这里有问题:

  1. MainWindow.CloseTab(myCurrentPage1Tab); 行之后 Page1 的内存分配会发生什么情况?

  2. 如果MainWindow.CloseTab(myCurrentPage1Tab); 行后面有代码,Page1 的内存分配会怎样?

  3. Page1 何时会从内存中完全释放?

  4. 有没有更好(更有效)的方法来实现这一点?

这个简化的场景是我的 WPF 应用程序一直在发生的事情,我担心这是否是一种安全的方式来管理我的应用程序的选项卡项和内存。

【问题讨论】:

  • 从标签控件中删除标签并不意味着您的标签未被引用,如果它是一次性的,您也应该处置标签。
  • 请注意,在调用myTabControl.Items.Remove(tab) 之前设置tab = null 没有多大意义,即使在伪代码中也是如此。
  • @Clemens 当然不是,我会编辑它,谢谢。
  • @LaurentLequenne 你能扩展你的答案吗?
  • 我建议正确处理选项卡,而不是将其设置为空。将其设置为 null 将起作用,但是,垃圾收集器启动并完全处理它需要一段时间

标签: c# wpf memory-management


【解决方案1】:
  1. Page1 的实例将有资格进行垃圾回收,前提是它没有被任何其他仍然存在的对象引用。
  2. 没有额外的内容,除非“MainWindow.CloseTab(myCurrentPage1Tab); 行之后的代码”对 Page1 引用执行了某些操作,从而阻止收集实例。
  3. 当垃圾收集器收集它时。何时发生这种情况是不确定的,即您并不真正知道它何时发生并且您不应该真正关心。
  4. 好吧,没有理由显式调用GC.Collect。这几乎总是一个坏主意。如果您的应用程序中不再引用 Page1 的实例,那么无论如何都会最终收集它。另外,我不知道您为什么要使用静态方法,但我想那是另一回事了。

总而言之,您应该简单地确保代码中没有引用使页面的存活时间超过必要的时间,但要远离垃圾收集器。

【讨论】:

  • 很遗憾,我有一些GC.Collect() 电话,现在我无法删除它们。我在这里、SO 和 MSDN 论坛上开始了几次关于内存和内存泄漏的讨论。由于我的应用程序内存分配不佳,因此有时我需要调用 GC...
【解决方案2】:

1-3

当垃圾收集器可以这样做时,它会从内存中删除未引用的控件。具体何时发生取决于您的应用程序正在做什么。

收集器何时清理某些控件通常并不重要。如果对您有影响,那么您的设计可能有问题。

4

取决于你在做什么。几乎所有的开发团队都使用 mvvm 和 wpf。通常的方法是将一组视图模型绑定到该选项卡控件的项目源,并将它们模板化到选项卡中。删除选项卡将涉及从该列表中删除视图模型。

使用这种方法,只有当前选项卡会被模板化到 UI 中。

您的描述使这听起来很像导航。用于 mvvm 样式导航的常见模式是 viewmodel 首先(你应该能够谷歌一堆示例)。本质上,这将涉及从一个窗口视图模型中公开一个属性,该窗口视图模型将为当前视图保存一个视图模型。这将绑定到 contentcontrol 的内容并根据数据类型模板化到 UI 中。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2015-09-14
    • 2021-08-23
    • 2017-06-16
    • 2011-11-29
    • 2010-12-04
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多