当Tab从Items集合中删除时,内存会发生什么?

问题描述 投票:0回答:2

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

假设这种情况:

我有我的应用程序的MainWindow,它有TabControl。为了从其集合中删除项目,我正在使用MainWindow的静态函数,如下所示:

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. 在qazxsw poi line之后,Page 1的内存分配会发生什么?
  2. 如果在qazxsw poi line之后有代码,那么第1页的内存分配会发生什么?
  3. 什么时候Page1将从内存中完全释放?
  4. 有没有更好(更有效)的方法来实现这一目标?

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

c# wpf memory-management
2个回答
1
投票
  1. MainWindow.CloseTab(myCurrentPage1Tab);的实例将有资格进行垃圾收集,前提是它没有被任何其他仍然活着的对象引用。
  2. 没有其他的,除非“MainWindow.CloseTab(myCurrentPage1Tab);行之后的代码”与Page1引用有关,阻止实例被收集。
  3. 当垃圾收集器收集它。当这种情况发生时是不确定的,即你真的不知道它何时发生,你不应该真正关心。
  4. 好吧,没有理由明确调用MainWindow.CloseTab(myCurrentPage1Tab);。这几乎总是一个坏主意。如果您的应用程序中不再引用Page1的实例,则无论如何最终都会收集它。此外,我不知道你为什么使用静态方法,但我想这是另一个故事。

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


0
投票

1-3

垃圾收集器将在内存中删除未引用的控件。究竟何时发生这种情况取决于您的应用程序正在做什么。

当收集器清理某些控件时,通常并不重要。如果它对你有用,那么你的设计可能有问题。

4

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

使用这种方法只会将当前选项卡模板化为UI。

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

© www.soinside.com 2019 - 2024. All rights reserved.