2011-01-19 3 views
5

J'ai passé beaucoup de temps récemment à essayer de comprendre pourquoi l'impression est si lente dans l'application sur laquelle je travaille (.Net 4.0, WPF front-end) et je suis tout hors des idées (25 minutes et plus pour imprimer 150 pages). J'ai essayé les différentes méthodes d'impression (PrintDialog, XpsDocumentWriter, VisualsToXpsDocument) à la fois avec des données vectorielles directement à partir des contrôles et aussi en rendant les contrôles (RenderTargetBitmap) d'abord et en envoyant des images, mais chaque méthode donne à peu près la même résultats. Il est intéressant lorsque vous utilisez le VisualsToXpsDocument pour effectuer une écriture par lots, je peux créer le contenu pour 186 pages dans le temps qu'il faut le cadre d'impression pour traiter 21 pages. Quelque chose ne va vraiment pas ici. Pour m'assurer que ce n'était pas seulement un problème avec la complexité de certains contrôles de l'application, j'ai créé une application de démonstration autonome qui contient juste une grille de données remplie de 4000 lignes de données statiques et de 8 colonnes environ. Il n'y a pas de problèmes de performances avec la grille de données elle-même, juste avec l'impression. Voici l'approche la plus acceptée que j'utilise qui donne de mauvais résultats.Impression très lente à partir de WPF

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

Alternativement, si j'utilise le code suivant, l'appel à EndBatchWrite() sera touché très rapidement, avec le reste du processus d'impression de prendre beaucoup plus longtemps.

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

Alors qu'est-ce que je fais mal ici? Est-ce que j'envoie les mauvaises données à l'imprimante? Y a-t-il un secret que je ne vois pas?

EDIT - Ceci est valable pour les imprimantes physiques ainsi que les imprimantes de fichiers à savoir d'imprimante XPS, PDF, etc.

Cheers,

Sam.

Répondre

0

C'est à peu près ce que je fais, ce qui est très rapide pour moi:

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

Je ne pas utiliser la boucle que vous utilisez comme je ne l'ai jamais eu besoin. Je laisse juste aller, et traiter toutes les erreurs car elles arrivent plus tard (c'est-à-dire après que j'ai déjà vérifié l'état de l'imprimante avant la main). Pour vérifier l'état de l'imprimante, il vous suffit de regarder les propriétés d'état de la file d'attente d'impression que vous utilisez.

J'espère que cela aide de quelque façon que ce soit.

+0

Le travail d'impression apparaissant dans la file d'attente d'impression est-il plutôt important? J'ai eu ce problème il y a 3 ans et je me souviens à peine comment je l'ai résolu. Cela avait à voir avec le fait que dans certaines circonstances, le système d'impression WPF pixelliserait le contenu au lieu de générer du contenu qui pourrait être directement converti en postscript. –