当我设置WPF子窗口的Owner属性时,我是否阻止它被垃圾收集?

时间:2011-10-05 21:42:21

标签: c# wpf garbage-collection

如果父窗口A将对自身的引用传递给子窗口B(通过构造函数),以便B可以将其所有者属性设置为A,这是否意味着子窗口B不会被垃圾收集,因为父窗口A保持活动状态申请的期限?

如果是这种情况,在WPF窗口之间创建干净的父/子关系的最佳方法是什么?对于这种关系,是否存在弱引用的概念?

更新:大脑失败。好的,我不应该在下午这么晚问这个问题。我的问题太复杂了。我的大脑颠倒了GC的逻辑,并且认为孩子无法收集,因为它引用了其他完全错误的东西。感谢所有回答的人。

3 个答案:

答案 0 :(得分:2)

我创建了你提到的Windows,并添加了一些代码:

// XAML in Window A

<StackPanel>
    <Button Click="Button_Click">Show Window</Button>
    <Button Click="Button_Click_1">Garbage Collect</Button>
</StackPanel>

// Code in Window A
 private void Button_Click(object sender, RoutedEventArgs e)
        {
            WindowB windowB = new WindowB(this);
            windowB.Show();
        }

        private void Button_Click_1(object sender, RoutedEventArgs e)
        {
            GC.Collect();
        }

    // Code in WindowB
    public WindowB(WindowA windowA)
    {
        this.Owner = windowA;
        InitializeComponent();
    }

    ~WindowB()
    {
        Console.WriteLine("Gone up in a puff of smoke");
    }

关闭B并按下第二个按钮后,析构函数就会运行。希望这能回答这个问题。

答案 1 :(得分:1)

只要堆栈中没有对它们的引用,对象就有资格进行垃圾回收。出于这个原因,只要您在window B中保留对window A的引用,那么它将永远不会被垃圾回收。

为了使其符合GC条件,您必须将对它的任何引用显式设置为null或其他对象引用。

答案 2 :(得分:1)

  

如果父窗口A将对自身的引用传递给子窗口B(通过   构造函数)以便B可以将其所有者属性设置为A,这是否意味着   由于父窗口A,子窗口B不会被垃圾收集   在申请期间保持活力?

正确,子窗口B一直存在,直到父窗口A存在,因为从父窗口到WindowB有一个实时引用。

  

如果是这种情况,创建清洁的最佳方法是什么   WPF窗口之间的父/子关系?有没有一个概念   对这种关系的弱引用?

当WindowB关闭时,清除对窗口B的父窗口引用。通过这种方式,没有对WindowB的实时引用,并且它有资格收集垃圾。

parentWindow.WindowB = null;

还有一件事,在所有Disposable对象超出范围之前调用Dispose方法是一个好习惯。您可以对本地/一次性对象使用using语句。