2011-04-25 69 views
1

警告:这是我第一个'真正'的WPF应用程序。我确定这是一个逻辑错误,我有一个地方,但无法弄清楚我应该在哪里寻找。WPF Window.Close内存泄漏

我有一个自助服务终端类型的应用程序,循环通过各种窗口,每个窗口显示不同类型的数据。我(目前)通过一个定时器来控制它们,并且应用程序运行良好,直到我最终达到内存不足异常。

我的代码通过Windows转动如下:

private Window activeWindow; 

private void ShowNextTaskWindow(ITask task) { 

    Window nextWindow = windowManager.GetWindowForTask(task); 

    nextWindow.Show(); 

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

} 

的窗口管理类只实例化窗口的适当类型 - 即NewsWindow或视频窗口,根据任务类型:

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的适当方法可以完成一些布局工作(设置窗口大小,控制大小等)。

我的问题是,应用程序只是继续消耗内存,直到它最终崩溃与内存不足异常 - 我似乎无法找出我失去了什么东西。

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

任何想法?

+0

你确定不是泄漏内存的窗口中的控件之一吗?如果您使用空窗口运行应用程序,是否会发生内存不足异常? – 2011-04-25 19:35:23

+0

你的窗口是否拥有非托管资源?考虑使用MVVM设计模式 - 您当前的体系结构不是非常WPF风格的。 – 2011-04-25 20:17:46

+0

非常像这个http://stackoverflow.com/questions/2860965/wpf-memory-leak的答案,我发现一个案例,我确实有一个事件处理程序,用户没有正确处理。我已经修复了 - 但总体而言,仍然遭受同样的问题。如果我想知道*我正在“做错了”,那就去看MVVM吧。谢谢,@Danny Varod – reallyJim 2011-04-26 21:59:28

回答

0

你真的应该使用CLR Profiler找出哪些对象,泄漏,消除了泄漏源...

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

根据实际发生的情况,重复使用Windows可能会“阻止泄漏”(尽管您仍应该找出解决方法并以正确的方式解决问题)。

+0

是的,我和你在一起。目前重写为MVVM,目的是尽可能重用。虽然没有使用过该工具,但会尝试运行该应用程序。谢谢! – reallyJim 2011-04-28 19:21:25

0

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

关闭()文件中的注释部分明确提到这样的场景: http://msdn.microsoft.com/en-us/library/system.windows.forms.form.close.aspx

+0

你的链接引用winforms,而OP使用WPF窗口不知道WPF窗口是否遭受同样的问题。 – ChrisWue 2011-04-25 23:45:22

0

要找到“泄漏”你必须首先做一些分析。

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

我看到了所有窗口类型的行为 - 它并不局限于单一窗口类型。 – reallyJim 2011-04-26 21:55:44