当尝试执行由于对某些资源的临时或永久限制而可能失败的任务时,我倾向于使用退避策略。消息队列和套接字打开等各种事物都遵循了这种策略。
这种策略的一般过程如下。
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 存在(更永久的)问题。此知识库文章指出 .NET 3.5SP1(您的打印驱动程序可能是客户端)中的 WPF 中存在内存泄漏。
如果退避策略不能解决您的问题(如果它是长期进程中的泄漏,则可能无法解决),您可能需要尝试应用修补程序。我,我会在虚拟机中复制问题,然后修补它来测试它(但我是一个极端的偏执狂)。
它是通过谷歌搜索和检查这里PresentationCore Insufficient memory to continue the execution of the program
的第一个链接找到的。在该页面上搜索字符串“与此问题相关的修补程序”。