Does the WPF DocumentPaginator keep all DocumentPages in memory until it finishes a print job?
Strictly theoretical question concerning WPF's DocumentPaginator:
When using the WPF DocumentPaginator class to print a multi-page document, does the paginator keep all of the DocumentPages it requests over the history of the print job in memory until the document finishes printing? Or does it ever dispose of any DocumentPages it no longer needs before the print job is finished (i.e. to free up memory)? Is there a way to manually tell the paginator to free old/unneeded DocumentPages in the course of printing without hitting an exception?开发者_如何转开发
Many thanks for your help with this!
I had exactly the same problem as you have.
It doesnt dispose the Pages which got loaded earlier. What I did to solve this issue was to hold a reference to the loaded page at the end of the GetPage() Method and dispose the last loaded page in the beginning of the GetPage Method.
here the answer to your aditional question:
I have the impression the implementation of System.Windows.Controls.PrintDialog.Print(DocumentPaginator, title) is something like that:
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
}
}
if the implementation is really something like that, a local reference to each processed page stays alive (in the dictionary) until the method execution finished. --> No memory will get freed.
What i did to avoid that (GetPage implementation in the class which extends 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;
}
And at the end you should implement the IDisposable interface and in the Dispose Method clean up the lastLoadedPage field to free the memory of the last page too.
Look into System.Windows.Xps.VisualsToXpsDocument
This fixes the problem I have running out of memory when creating large xps document. Also look into PrintQueue.CreateXpsDocumentWriter(somePrintQueue)
. Sorry, I don't have enough reps to just make this a comment.
精彩评论