预生成Graphics对象以提高打印性能

时间:2016-04-13 12:04:58

标签: c# performance printing

我有一个打印发票的应用程序。我希望能够在后台任务/流程中预先生成发票,这样我就可以减少在用户提示或其他自动化事件时将文档发送到打印机所需的停机时间。我正在寻找这样的东西......

Graphics _g;

// background task would call this method
void GenerateInvoice(Invoice i)
{
  _g = ???? // ????
  _g.DrawImage...
  _g.DrawString....
}

// user action, or automation event, would call this method...
void PrintInvoice()
{
  if (_g == null) 
    throw new DocumentNotPreparedException();

  PrintDocument pd = new PrintDocument();
  pd.PrinterSettings.PrinterName = "My Fast Printer";
  pd.PrintPage += PrintHandler;
  pd.Print();
}

void PrintHandler(object o, PrintPageEventArgs e)
{
  // ????
  e.Graphics = _g;
}

有关在' ???'及其周围需要做什么的任何建议。段?

1 个答案:

答案 0 :(得分:0)

  

我希望能够在后台任务/流程中预先生成发票,这样我就可以减少将文档发送到打印机所需的停机时间

第一步是确保您知道"停机时间的来源"是。瓶颈存在于您自己的程序的渲染代码中是不常见的。大多数情况下,打印机慢速的主要来源是打印驱动程序本身(例如,具有大量代码的驱动程序和必须被分页以处理作业的数据),或者处理需要客户端光栅化的打印机页面图像(需要大量内存来支持所需的高分辨率位图,这在某些机器上可能会很慢,当然会大大增加将这些光栅化图像发送到打印机所花费的时间,无论你在哪个连接上#&# 39;重新使用)。


如果您确定自己的代码速度很慢,并且在您确定自己的代码基本上与您可以实现的效率相同之后,那么您可以将预渲染视为改善用户体验的一种方式。这里有两个主要选项:渲染到位图,然后渲染为metafile

就个人而言,我会推荐后者。元文件将保留原始渲染命令,从而提供与分辨率无关且内存有效的打印数据表示。如果您的输出主要包括线条图和文本输出,那么这将特别有价值。

如果您改为渲染到位图,则需要确保为打印作业分配至少与打印机支持的分辨率相同的位图。否则,您将在此过程中失去显着的图像质量,并且您的打印输出看起来不会很好。请注意,如果你采用这种方式,你可能会遇到同样与内存相关的减速风险,这在理论上是直接处理打印机驱动程序时会出现问题。

最后,就两种技术之间的选择而言,如果您的打印作业输出主要包含已经处于或接近分辨率的大量位图,则位图方法可能优于元文件方法的一种情况由打印机支持。在这种情况下,将这些位图展平为单个页面大小的位图实际上可以减少内存占用量。将它们绘制到元文件中需要将每个单独的位图存储在元文件中,如果这些位图的总大小大于单页大小的位图,那么当然会使用更多的内存。将它们展平为单个位图可以避免在内存中同时存在大量单个大型位图。


但实际上,上述内容主要是理论上的。您建议为您的打印代码添加高度复杂性,以便解决最有可能无法解决的问题,因为问题很可能不在于您自己的代码中所有。在走这条路之前,你应该确保你仔细检查了慢速打印的原因。