WPF Window.Close内存泄漏

时间:2011-04-25 19:18:03

标签: .net wpf memory-leaks

警告:这是我的第一个“真正的”WPF应用程序。我确定这是我在某个地方的逻辑错误,但无法弄清楚我应该在哪里看。

我有一个自助服务终端类型的应用程序,它循环遍历各种窗口,每个窗口都显示不同类型的数据。我(现在)通过一个计时器来控制这些,并且应用程序运行良好,直到我最终达到Out of Memory Exception。

我在窗口中旋转的代码如下:

private Window activeWindow;

private void ShowNextTaskWindow(ITask task) {

    Window nextWindow = windowManager.GetWindowForTask(task);

    nextWindow.Show();

    if (activeWindow != null) {
        activeWindow.Close();
    }
    activeWindow = nextWindow;

}

windowManager类根据任务类型简单地实例化相应类型的窗口 - 即NewsWindow或VideoWindow:

public Window GetWindowForTask(ITask task) {

    Window taskWindow = null;

    switch (task.TaskType) {
            case TaskType.Web:
                taskWindow = new WebWindow(task as WebTask);
                break;

            case TaskType.Rss:
                taskWindow = new RssWindow(task as RssTask);
                break;

     ..... etc ......

    }
    return taskWindow;
}

每个窗口都有(仅)在构造函数中添加的一个事件处理程序,如下所示:

 Loaded += new RoutedEventHandler(Window_Loaded);

当然,还有一个名为Window_Loaded的适当方法可以进行一些布局工作(设置窗口大小,控件大小等)。

我遇到的问题是应用程序只是继续占用内存,直到它最终因Out of Memory异常而崩溃 - 我似乎无法弄清楚我在哪里遗漏了什么。

据我了解,调用Window.Close()应该摆脱窗口,所以我迷失在哪里寻找问题。

有什么想法吗?

3 个答案:

答案 0 :(得分:0)

当你在nextWindow上调用.Show()时,它会导致activeWindow不可见,因此当你调用Close()时,activeWindow不会丢弃它的控件。

Close()文档在“备注”部分中明确提到了这种情况: http://msdn.microsoft.com/en-us/library/system.windows.forms.form.close.aspx

答案 1 :(得分:0)

要找到“泄漏”,您必须先进行一些分析。

  1. 通过测试程序并仅使用一种类型的窗口来查找导致泄漏的窗口。让程序运行直到它失败或你确定这个窗口类型没有引起任何问题。对所有类型重复此操作。
  2. 找到有问题的窗口类型后,检查其代码并逐个关闭/打开功能以查找问题。

答案 2 :(得分:0)

您应该使用CLR Profiler来确定哪些对象正在泄漏并消除泄漏源...

但我也建议,假设您在少量IT工作中骑车,重新使用Window实例可能是个好主意。在GetWindowForTask中,您可以使用字典(可能是ConditionalWeakTable)将Windows与任务相关联。如果一个任务已有一个窗口,只需返回它,不要实例化一个新窗口。

根据实际情况而定,重复使用Windows可能会“阻止泄漏”(尽管你仍然应该弄清楚并以正确的方式解决它)。