【问题标题】:WPF OutOfMemory Exception after displaying images a couple of times显示图像几次后出现 WPF OutOfMemory 异常
【发布时间】:2016-02-24 18:44:55
【问题描述】:

我使用 wpf 并利用 wpf 集装箱船模型创建了一个投票系统。在系统中,正在使用一系列显示候选图片的用户控件。最终用户完成投票后,系统会自动退出登录,等待下一个登录。连续投票数次后,图片开始随机一张一张丢失。当我检查时,这是因为内存不足异常。随着我继续对其进行压力测试,越来越多的图片开始消失。我有一种预感,是因为系统没有处理之前显示的窗口和用户控件和图片。我可以做些什么来处置窗口或至少确保在关闭窗口后处置已显示的图片?

【问题讨论】:

    标签: wpf image user-controls window dispose


    【解决方案1】:

    你可以做一些事情。首先是使用内存分析器。我个人喜欢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 类将保存对您的窗口的引用,以防止它被关闭。始终确保您的计时器在窗口关闭时停止。

    【讨论】:

    • 哦,抱歉,我没有提供足够的详细信息。该系统是一个校园投票系统。图像存储在数据库中,而不是硬盘中。因此,每当学生登录时,该特定学年候选人的图像将从数据库中加载到单独的列表视图中。之后,下一个学年,必须加载新一批具有新图像的候选人并在投票环节使用
    • 在不了解的情况下,我真的不能说为什么窗口不能正确关闭。如果用户关闭它但它仍留在内存中,那么您就有内存泄漏。问题可能涉及很多方面。我仍然建议运行分析器,它可以帮助您找到问题。
    猜你喜欢
    • 2011-10-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-08-10
    相关资源
    最近更新 更多