#c# #wpf #printing
#c# #wpf #печать
Вопрос:
У меня возникла небольшая проблема при использовании PrintDialog.PrintVisual
, поскольку, похоже, это вызывает утечку памяти.
В этом приложении я создаю элемент управления WPF, который используется только для печати, он никогда не отображается на экране. Вот пример кода:
Вызов печати
public void PrintDocument()
{
PrintUserControl printControl = new PrintUserControl();
printControl.Print();
}
Пользовательский элемент управления печатью
public class PrintUserControl
{
public PrintUserControl()
{
InitializeComponent();
}
public void Print()
{
const double width = 5.8 * 96;
const double height = 8.3 * 96;
this.Measure(new Size(width, height));
this.Arrange(new Rect(new Size(width, height)));
this.UpdateLayout();
var dlg = new PrintDialog();
PageMediaSize pageMedia = new PageMediaSize(PageMediaSizeName.ISOA5);
dlg.PrintTicket.PageMediaSize = pageMedia;
dlg.PrintVisual(this, "FooDocument");
}
}
Я профилировал это приложение, и при вызове PrintUserControl.Print
метода возникает утечка памяти, многие экземпляры LayoutEventList ListItem
и ConditionalWeakTable
. Если я закомментирую PrintUserControl.Print
метод, то утечек не будет, но, очевидно, ничего не печатается.
Разве я не избавляюсь от того, что должен?
Комментарии:
1. Проверьте объекты, которые вы используете, на наличие методов удаления. Если они у них есть, вызовите их. Кроме того, помните, что объекты НЕ исчезают, когда они выходят за пределы области видимости, только при запуске GC, что может произойти через некоторое время.
2. К сожалению, ни один из объектов не является одноразовым. Я использую ANTS performance profiler и отслеживаю IDisposable объекты, но они не отображаются.
3. Сообщает ли это вам, что готово для GC? Я думаю, что Sysinternals Process Explorer сделает это, если нет.
4. Двумя «классами», которые являются Gen2 и растут, являются
LayoutEventList ListItem
иConditionalWeakTable
5. Изменил это на ответ, так как комментарий стал слишком длинным…
Ответ №1:
Итак, они были должным образом очищены, но GC не запустился и не запустится, пока не решит, что это необходимо. (Обычно это происходит, когда на компьютере не хватает памяти.)
В принципе, так оно и есть .NET работает, и в целом, как работают языки, собирающие мусор.
Преимущество в том, что вам не нужно беспокоиться о том, следует ли использовать Free или delete, или об утечках памяти, когда вы забываете использовать либо то, либо другое; недостатком является то, что ваш процесс использует больше памяти, пока сборщик не приступит к очистке.
Он не будет запускаться до тех пор, пока не возникнет необходимость в очистке, поскольку в противном случае Он забирает ресурсы (процессор и т. Д.) Из вашего приложения, Когда они действительно не нужны в другом месте. Это произойдет только при соблюдении некоторых условий, таких как нехватка доступной системной памяти. Я считаю, что обстоятельства, при которых GC решает выполнить, являются «деталями реализации», и на них не следует полагаться, поскольку они будут меняться между ними.СЕТЕВЫЕ версии.
Разумный вариант — это из MSDN. Вы также можете выполнить поиск по «недетерминированной финализации», в которой было задействовано несколько человек, когда .NET был в оригинальной бета-версии iuts.
Комментарии:
1. По прошествии времени моя машина с 2 ГБ оперативной памяти использует 2 ГБ, так что это не значит, что GC не вызывается. Используя ANTS profiler, я могу вручную вызвать полный GC, и элементы все еще там.
2. ОК. Должно быть, я неправильно понял, что вам показывал ANTS — извините. Что такое LayoutEventList? Поиск этого не дает ничего особенного. Где вы это используете? Где это определено?