Я создал систему голосования с использованием wpf и запустил модель корабля wpf. В системе используется серия пользовательских элементов управления, отображающая изображения кандидатов. после того, как конечный пользователь завершит голосование, система автоматически выйдет из системы и ждет следующего входа в систему. После нескольких последовательных голосовых кастингов изображения начинают пропадать один за другим случайным образом. Когда я проверил, это было из-за исключения из памяти. Поскольку я продолжаю подчеркивать тест, все больше и больше фотографий начинают исчезать. Я подозреваю, что это произошло потому, что система не удаляет предыдущие окна и пользовательские элементы управления и изображения, которые были отображены. Что я могу сделать, чтобы удалить окно или, по крайней мере, убедиться, что изображения, которые были отображены, будут удалены после закрытия окна?Исключение WPF OutOfMemory после отображения изображений пару раз
ответ
Несколько вещей, которые вы можете сделать. Сначала будет использоваться профилировщик памяти. Я лично люблю 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 будет содержать ссылку на ваше окно, чтобы он не закрывался. Всегда следите за тем, чтобы таймеры остановились, когда окно закрывается.
О, извините, я не представил достаточно подробностей. система - система голосования на кампусе. изображения хранятся в базе данных, а не на жестком диске. поэтому всякий раз, когда студент входит в систему, изображения кандидатов в этом конкретном учебном году будут загружены из базы данных в отдельные виды списков. После этого, следующий учебный год, новая партия кандидатов с новыми изображениями должна быть загружена и использована в голосовании. –
Не зная об этом больше, я не могу сказать, почему окно не будет корректно закрываться. Если пользователь закрывает его, но он остается в памяти, тогда у вас есть утечка памяти. Вопрос может быть большим количеством вещей. Я бы по-прежнему предлагал запустить профилировщик, и это может помочь вам найти проблему. – Kelly