我将在这个问题中使用伪代码,所以请在理论方面参考这个(我的意思是,会有一些简化)
假设这种情况:
我有我的应用程序的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;
}
此函数应创建新的选项卡,为其分配内容,然后使用MainWindow.CloseTab(myCurrentPage1Tab);
关闭包含Page1的当前选项卡。
以下是问题:
第1 页在
MainWindow.CloseTab(myCurrentPage1Tab);
行之后的内存分配会发生什么情况?如果
MainWindow.CloseTab(myCurrentPage1Tab);
行后有代码,第 1 页的内存分配会发生什么情况?Page1何时从内存中完全释放?
有没有更好(更有效)的方法来实现这一目标?
这种简化的方案是我的 WPF 应用程序一直在发生的情况,我担心这是否是管理选项卡项和应用程序内存的安全方法。
Page1
的实例将有资格进行垃圾回收,前提是它未被任何其他仍处于活动状态的对象引用。- 没有额外的内容,除非"
MainWindow.CloseTab(myCurrentPage1Tab);
行后的代码"对阻止收集实例的Page1
引用执行某些操作。 - 当垃圾回收器收集它时。当这种情况发生时是不确定的,也就是说,你真的不知道它什么时候发生,你不应该真正关心。
- 好吧,没有理由明确称
GC.Collect
.这几乎总是一个坏主意。如果应用程序中不再引用Page1
的实例,则最终仍将收集该实例。另外,我不知道你为什么使用静态方法,但我想那是另一回事了。
总而言之,您应该简单地确保代码中没有引用使页面存活的时间超过必要的时间,但不要妨碍垃圾回收器。
1-3
垃圾回收器将在执行此操作时从内存中删除未引用的控件。确切的时间将取决于您的应用正在执行的其他操作。
收集器清理某些控件的确切时间通常并不重要。 如果它对你有用,那么也许你的设计有问题。
四
取决于你在做什么。几乎所有开发团队都使用带有 wpf 的 mvvm。通常的方法是将视图模型的集合绑定到该选项卡控件的 itemssource 中,并将其模板化到选项卡中。 删除选项卡将涉及从该列表中删除视图模型。
使用此方法,只有当前选项卡会模板化到 UI 中。
不过,您的描述使这听起来很像导航。用于 mvvm 样式导航的常见模式是视图模型优先(您应该能够谷歌一堆示例)。实质上,这将涉及从窗口视图模型公开属性,该模型将保存当前视图的视图模型。这将绑定到内容控件的内容,并根据数据类型模板化到 UI 中。