我使用wpf创建了一个投票系统,并将wpf集装箱船模型大写。在系统中,正在使用一系列显示候选图片的用户控件。在最终用户完成投票后,系统将自动注销并等待下一个投票。在连续几次投票后,图片开始随机逐个丢失。当我检查时,这是因为内存不足异常。随着我继续对它进行压力测试,越来越多的图片开始消失。我有预感,因为系统没有处理以前的窗口和用户控件以及已显示的图片。如何处理窗口或至少确保在关闭窗口后处理已显示的图片?
答案 0 :(得分:0)
你可以做的一些事情。首先是使用内存分析器。我个人喜欢RedGate ANTS Memory Profiler它会告诉你,如果你的物品被清理干净,我相信它们可以免费试用。
您的图像如何显示?窗口是否从磁盘加载它们?如果有少量图像,我建议将它们放在ResourceDictionary中,如下所示:
<BitmapImage UriSource="/MyApp.Client;component/Images/Pinned.png" x:Key="Pinned" PresentationOptions:Freeze="True" />
<BitmapImage UriSource="/MyApp.Client;component/Images//Unpinned.png" x:Key="Unpinned" PresentationOptions:Freeze="True" />
然后在你的XAML中你可以使用:
<Image Source="{StaticResource: Unpinned}"/>
这将确保您的图片仅加载一次。所有需要它的东西都会引用它。
另请注意,如果您在窗口上订阅了任何活动,则可能会阻止您的窗口关闭。窗口关闭时,您应该始终取消引用您的事件。例如:
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
Loaded += DoStuff();
}
private RoutedEventHandler DoStuff()
{
//some code here
}
protected override void OnClosing(CancelEventArgs e)
{
base.OnClosing(e);
Loaded -= DoStuff();
}
}
注意通用方法。例如,如果你这样做:
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
Loaded += (o, e) =>
{
//Do stuff here
};
}
}
没有办法取消引用,因为该方法是通用的,因此没有什么可以放在你的关闭中摆脱它。这是内存泄漏和防止窗口关闭的常见问题。
经常被忽视的另一个常见的是Timer类。如果启动计时器然后在不停止计时器的情况下关闭窗口,则Timer类将保留对窗口的引用,以防止它被关闭。窗户关闭时,请务必确保您的计时器停止。