Silverlight ChildWindow内存泄漏问题

3

有人知道如何解决使用ChildWindow时SL3中的内存泄漏问题吗?

请参考下面的代码片段:

 private void Button_Click(object sender, RoutedEventArgs e)
    {
        var window = new ChildWindow();

        window.Closed += new EventHandler(window_Closed);

        window.Show();
    }

    void window_Closed(object sender, EventArgs e)
    {
        ((ChildWindow)sender).Closed -= new EventHandler(window_Closed);

        WeakReference reference = new WeakReference(sender);

        GC.Collect();

        GC.WaitForPendingFinalizers();

        bool isControlAlive = a.IsAlive;
    }

每次我打开和关闭子窗口时,它总是显示为仍然“活着”,并且当我在任务管理器中监视iexplore实例时,内存每次都会增加。

请帮忙解决。

谢谢。

Chris

1个回答

4
据我所知,目前还没有官方的解决方案。 这个页面 描述了内存泄漏的性质:

... [ChildWindow] 订阅了 RootVisual_GotFocus 多次,但只在关闭时取消订阅一次。 这导致 ChildWindow 永久留在内存中,附加到 RootVisual 的 GotFocus 事件上。

根据评论部分的内容,您可以按照以下方式修改 Silverlight Toolkit 代码以解决问题:

修改 ChildWindow.cs 上的 ChildWindow_LostFocus 函数(第731行),以在再次添加之前减去 RootVisual_GotFocus 监听器:

Application.Current.RootVisual.GotFocus -= this.RootVisual_GotFocus;
Application.Current.RootVisual.GotFocus += this.RootVisual_GotFocus;

请注意,可能不仅是GotFocus事件引起了问题。SizeChanged事件似乎也是罪魁祸首。 - Ben Hoffstein
我看了关于 GotFocus 事件的评论-并不知道 SizeChanged 事件。所以它基本上是一个需要取消订阅的事件处理程序 - 只需浏览 ChildWindow 类的代码以找出是哪个事件即可? - Chris
这个问题似乎在Silverlight 5中已经修复。System.Windows.Controls.ChildWindow类中有一个private bool _attachedRootVisualListener字段,在订阅RootVisual_GotFocus事件之前进行检查。 - apdevelop

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接