【问题标题】:Batch printing exception批量打印异常
【发布时间】:2009-12-22 12:16:28
【问题描述】:

将多个 .xps 文档打印到物理打印机时出现此错误

Dim defaultPrintQueue As PrintQueue = GetForwardPrintQueue(My.Settings.SelectedPrinter)
Dim xpsPrintJob As PrintSystemJobInfo
xpsPrintJob = defaultPrintQueue.AddJob(JobName, Document, False)

文档被成功假脱机,直到发生打印作业异常

InnerException 内存不足,无法继续执行程序。

来源是PresentationCore.dll

我应该从哪里开始搜索?

【问题讨论】:

    标签: vb.net printing memory-leaks xps


    【解决方案1】:

    当尝试执行由于对某些资源的临时或永久限制而可能失败的任务时,我倾向于使用退避策略。消息队列和套接字打开等各种事物都遵循了这种策略。

    这种策略的一般流程如下。

    set maxdelay to 16 # maximum time period between attempts
    set maxtries to 10 # maximum attempts
    
    set delay to 0
    set tries to 0
    while more actions needed:
        if delay is not 0:
            sleep delay
        attempt action
        if action failed:
            add 1 to tries
            if tries is greater than maxtries:
               exit with permanent error
            if delay is 0:
                set delay to 1
            else:
                double delay
                if delay is greater than maxdelay:
                    set delay to maxdelay
        else:
            set delay to 0
            set tries to 0
    

    这允许进程在绝大多数情况下全速运行,但在开始发生错误时退出,希望给资源提供者时间来恢复。延迟的逐渐增加允许恢复更严重的资源限制,并且最大尝试捕获您所说的永久错误(或需要很长时间才能恢复的错误)。

    实际上,我更喜欢这种 try-it-and-catch-failure 方法而不是 check-if-okay-then-try 方法,因为如果检查和尝试之间发生变化,后者仍然经常会失败。这被称为“寻求宽恕胜于请求许可”方法,这种方法在大多数情况下对老板也很有效,而对妻子的频率则略低:-)

    一个特别有用的案例是一个程序,它为每个短暂的事务打开一个单独的 TCP 会话。在较旧的硬件上,已关闭的套接字(处于 TCP WAIT 状态的套接字)最终在再次被需要之前就消失了。

    但是,随着硬件变得更快,我们发现我们可以打开会话并更快地完成工作,而且 Windows 的 TCP 句柄已经用完(即使增加到最大值)。

    不必重新设计通信协议来维护会话,实施此策略是为了在事件句柄被饿死时允许正常恢复。

    诚然,这有点杂乱无章,但这是即将报废的遗留软件,其中错误修复通常足以使其正常工作,而且它被认为不够具有战略意义,不足以保证花费大量资金进行修复正确的。


    更新:可能是 PresentationCore 存在(更持久的)问题。此KB article 指出 .NET 3.5SP1(您的打印驱动程序可能是客户端)中的 WPF 中存在内存泄漏。

    如果退避策略不能解决您的问题(如果它是长期进程中的泄漏,则可能无法解决),您可能需要尝试应用修补程序。我,我会在虚拟机中复制问题,然后对其进行修补以对其进行测试(但我是一个极端的偏执狂)。

    它是通过谷歌搜索PresentationCore Insufficient memory to continue the execution of the program 并检查第一个链接here 找到的。在该页面上搜索字符串“与此问题相关的修补程序”

    【讨论】:

      【解决方案2】:

      在将新作业添加到队列之前,您应该检查队列状态。有关PrintQueue.IsOutOfMemory 属性和相关属性的更多信息,可以查询这些属性以验证队列是否处于错误状态。

      当然,pax 提示在访问打印机等资源时使用防御策略是最佳实践。对于初学者,您可能希望将添加作业的行放入 try 块中。

      【讨论】:

        【解决方案3】:

        您可能需要考虑启动一个新流程来处理每个文档的打印,与打印文档的工作量相比,开销应该较低。

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2017-12-21
          • 1970-01-01
          • 2010-09-26
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多