开发者

Very slow printing from WPF

I've spent a lot of time recently on trying to figure out why the printing is so slow in the application I'm working on (.Net 4.0, WPF front-end) and I'm all out of ideas (25+ minutes to print 150 pages).

I have tried the various methods of printing (PrintDialog, XpsDocumentWriter, VisualsToXpsDocument) both with vector data straight from the controls and also by rendering the controls (RenderTargetBitmap) first and just sending images out, but each method gives roughly the same results.

Interestingly when using the VisualsToXpsDocument to do a batch write, I can create the content for 186 pages in the time it takes the printing framework to process 21 pages. Something is really wrong here.

To make sure this wasn't just a problem with the complexity of some of the controls in the application, I created a standalone demo app that contains just a data grid filled with 4000 rows of static data and around 8 columns. There are no performance issues with the data grid itself, just with printing. Here's the most accepted approach I've been using that gives poor results.

        this.writer 
          = PrintQueue.CreateXpsDocumentWriter(this.SelectedPrinter.PrintQueue);

        PrintingDocumentPaginator paginator 
          = new PrintingDocumentPaginator(this.PrintConfiguration, 
                contentSize, pageSize, contentRect, this.printSource, false);

        this.writer.WritingProgressChanged += this.OnPrintingProgressChanged;
        this.writer.WritingCompleted += this.OnPrintingCompleted;
        this.writer.WritingCancelled += this.OnPrintingCanceled;

        this.writer.WriteAsync(paginator, 
                this.PrintConfiguration.PrintTicket, paginator.PageCount);

Alternatively if I use the following code, the call to EndBatchWrite() will be hit very quickly, with the rest of the print process taking much longer.

        this.writer 
          = PrintQueue.CreateXpsDocumentWriter(this.SelectedPrinter.PrintQueue);

        PrintingDocumentPaginator p开发者_如何学Pythonaginator 
            = new PrintingDocumentPaginator(this.PrintConfiguration, 
                    contentSize, pageSize, contentRect, 
                    this.printSource, this.useVectorData);

        this.writer.WritingProgressChanged += this.OnPrintingProgressChanged;
        this.writer.WritingCompleted += this.OnPrintingCompleted;
        this.writer.WritingCancelled += this.OnPrintingCanceled;

        VisualsToXpsDocument sdf 
          = (VisualsToXpsDocument)this.writer.CreateVisualsCollator();

        for (int i = 0; i < paginator.PageCount; i++)
        {
            sdf.WriteAsync(paginator.GetPageVisual(i));
        }

        sdf.EndBatchWrite();

So what am I doing wrong here? Am I sending the wrong data to the printer? Is there some secret I'm not seeing?

EDIT - This applies to physical printers as well as file printers i.e. XPS printer, PDF etc.

Cheers,

Sam.


This is pretty much what I do, which is really fast for me:

        LocalPrintServer localPrintServer = new LocalPrintServer();
        System.Printing.PrintQueue pq = new System.Printing.PrintQueue(localPrintServer, localPrintServer.DefaultPrintQueue.FullName);

        System.Windows.Xps.XpsDocumentWriter docWriter = System.Printing.PrintQueue.CreateXpsDocumentWriter(pq);
        PrintCapabilities pc = pq.GetPrintCapabilities();

        PageImageableArea pia = pc.PageImageableArea;

        if (docWriter != null)
        {
            DocumentPaginator paginator = ((IDocumentPaginatorSource)copy).DocumentPaginator;

            // Change the PageSize and PagePadding for the document to match the CanvasSize for the printer device.
            paginator.PageSize = new System.Windows.Size(pia.ExtentWidth, pia.ExtentHeight);

            // Send content to the printer.
            docWriter.Write(paginator);
        }

I don't use the loop that you use as I've never needed it. I just let it go, and deal with any errors as they arrive later (that is after I've already checked the printer status before hand). To check the printer status, you just look at the status properties on the printer queue, that you're using.

I hope that helps in any way.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜