Сохраняет ли WPF DocumentPaginator все DocumentPages в памяти, пока не завершит задание печати?
Строго теоретический вопрос относительно WPF DocumentPaginator:
При использовании класса WPF DocumentPaginator для печати многостраничного документа, сохраняет ли paginator все запрошенные им страницы документов за всю историю задания печати в памяти до тех пор, пока документ не завершит печать? Или он когда-либо удаляет какие-либо DocumentPages, которые ему больше не нужны, до завершения задания печати (то есть для освобождения памяти)? Есть ли способ, чтобы вручную сказать paginator освободить старые / ненужные DocumentPages в процессе печати без исключения?
Большое спасибо за вашу помощь с этим!
2 ответа
У меня была точно такая же проблема, как и у вас.
Он не располагает страницами, которые были загружены ранее. Чтобы решить эту проблему, я держал ссылку на загруженную страницу в конце метода GetPage() и располагал последнюю загруженную страницу в начале метода GetPage.
вот ответ на ваш дополнительный вопрос:
У меня сложилось впечатление, что реализация System.Windows.Controls.PrintDialog.Print(DocumentPaginator, title) выглядит примерно так:
Public void PrintDocument(DocumentPaginator paginator, string title)
{
Dictionary<int, DocumentPage> pages = new Dictionary<int DocumentPage>();
for(int i=0; i<paginator.PageCount(); i++)
{
pages.Add(i, paginator.GetPage(i));
UnknownPrinterEngine.SendPageToPrinter(pages(i)); //this is just imagination
}
}
если реализация действительно что-то в этом роде, локальная ссылка на каждую обработанную страницу остается активной (в словаре) до завершения выполнения метода. -> Нет памяти освободится.
Что я сделал, чтобы избежать этого (реализация GetPage в классе, который расширяет DocumentPaginator):
DocumentPage lastLoadedPage = null;
public DocumentPage GetPage(int pageNumber)
{
if(lastLoadedPage != null)
{
lastLoadedPage.Dispose()
}
//MyPrintControl should be your custom UserControl which represents the page to print
myPrintControl pageContent = new MyPrintControl();
pageContent.Width = PageSize.Width;
pageContent.Height = PageSize.Height;
pageContent.Measure(PageSize);
pageContent.Arrange(new Rect(new Point(0,0), PageSize));
DocumentPage actualPage = New DocumentPage(pageContent);
lastLoadedPage = actualPage;
return actualPage;
}
И, наконец, вы должны реализовать интерфейс IDisposable и в методе Dispose очистить поле lastLoadedPage, чтобы освободить память последней страницы.
Заглянуть в System.Windows.Xps.VisualsToXpsDocument
Это устраняет проблему, когда у меня не хватает памяти при создании большого документа xps. Также посмотрите в PrintQueue.CreateXpsDocumentWriter(somePrintQueue)
, Извините, мне не хватает представителей, чтобы просто сделать это комментарием.