警告:这是我的第一个“真正的”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()应该摆脱窗口,所以我迷失在哪里寻找问题。
有什么想法吗?
答案 0 :(得分:0)
当你在nextWindow上调用.Show()时,它会导致activeWindow不可见,因此当你调用Close()时,activeWindow不会丢弃它的控件。
Close()文档在“备注”部分中明确提到了这种情况: http://msdn.microsoft.com/en-us/library/system.windows.forms.form.close.aspx
答案 1 :(得分:0)
要找到“泄漏”,您必须先进行一些分析。
答案 2 :(得分:0)
您应该使用CLR Profiler来确定哪些对象正在泄漏并消除泄漏源...
但我也建议,假设您在少量IT工作中骑车,重新使用Window
实例可能是个好主意。在GetWindowForTask
中,您可以使用字典(可能是ConditionalWeakTable)将Windows与任务相关联。如果一个任务已有一个窗口,只需返回它,不要实例化一个新窗口。
根据实际情况而定,重复使用Windows可能会“阻止泄漏”(尽管你仍然应该弄清楚并以正确的方式解决它)。