Очень медленная печать из WPF - PullRequest
6 голосов
/ 19 января 2011

В последнее время я потратил много времени, пытаясь выяснить, почему печать выполняется так медленно в приложении, над которым я работаю (.Net 4.0, WPF front-end), и у меня нет идей (25+ минут для печати 150 страниц).

Я пробовал различные способы печати (PrintDialog, XpsDocumentWriter, VisualsToXpsDocument) как с векторными данными прямо из элементов управления, так и с помощью рендеринга элементов управления (RenderTargetBitmap) сначала и простоотправка изображений, но каждый метод дает примерно одинаковые результаты.

Интересно, что при использовании VisualsToXpsDocument для пакетной записи я могу создать контент для 186 страниц за то время, которое требуется инфраструктуре печати для обработки 21 страницы.,Здесь что-то действительно не так.

Чтобы убедиться, что это не просто проблема со сложностью некоторых элементов управления в приложении, я создал отдельное демонстрационное приложение, которое содержит только сетку данных, заполненную 4000 строкстатических данных и около 8 столбцов.С сеткой данных нет проблем с производительностью, только с печатью.Вот наиболее приемлемый подход, который я использовал, который дает плохие результаты.

        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);

В качестве альтернативы, если я использую следующий код, вызов EndBatchWrite () будет выполнен очень быстро, с остальной частью печатиПроцесс занимает гораздо больше времени.

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

        PrintingDocumentPaginator paginator 
            = 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();

Так что я здесь не так делаю?Я отправляю неправильные данные на принтер?Есть ли какой-то секрет, которого я не вижу?

РЕДАКТИРОВАТЬ - Это относится к физическим принтерам, а также к файловым принтерам, таким как принтер XPS, PDF и т. Д.

Cheers,

Sam.

1 Ответ

0 голосов
/ 14 апреля 2012

Это почти то, что я делаю, что для меня очень быстро:

        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);
        }

Я не использую цикл, который вы используете, потому что он мне никогда не был нужен. Я просто отпустил его и исправлю любые ошибки по мере их появления (то есть после того, как я уже проверил состояние принтера заранее) Чтобы проверить состояние принтера, достаточно взглянуть на свойства состояния в очереди принтера, которую вы используете.

Надеюсь, это поможет.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...