2

I have a very simple application that is printing TIFF files to a variety of networked printers. The printers are all installed on 3 different print servers, while the application runs on a separate machine. (Lets call them Print1,2,3, and App1.)

Most of the time this works well, but lately I have noticed that certain new printers (HP P4515x model using PCL6 drivers) are causing a spike in the number of handles opened by spoolsv.exe on App1. One document can raise the handles by 500, and they are never released, which eventually leads to the App1 machine having to be rebooted if this isn't caught in time. None of the actual print servers seem affected by this issue.

The code is doing something very similar in concept to this, but from a background service running under a domain account: MSDN Link. I am specifying the printer using the \print3\deptP4515x naming convention.

[Not sure if this goes on StackOverflow or ServerFault, but I think due to the possible driver issue, it should be on here?]

EDIT: I ran procexp and see that of the 1243 handle it has grown to, 1135 are this: Key HKLM\SOFTWARE\Hewlett-Packard\San Diego Shared IO

mpeterson
  • 255
  • 1
  • 11
  • Seems like it would go over better on SO, but maybe someone can help you here. – Dave Drager Oct 15 '09 at 14:08
  • 1
    The handles are opened by spoolsv.exe, so looks like the problem is in the Windows printing system, not in your application. – Massimo Oct 15 '09 at 14:32
  • I wouldn't close until we've determined if it's a code issue or a print subsystem issue. – Maximus Minimus Oct 15 '09 at 14:39
  • Easy to do: kill your application and see if the handles get released. – Massimo Oct 15 '09 at 14:42
  • The printing application does not have the handle problem, only the spoolsv.exe executable. (which is why i thought SF instead of SO) – mpeterson Oct 15 '09 at 15:03
  • That would be consistent with my Dispose theory - it may be the case that for this driver the handles aren't being automatically cleared when idle if you don't Dispose. Printing is an unmanaged/GDI thingie, so Disposing is important anyway, even outside of this specific case. – Maximus Minimus Oct 15 '09 at 16:25

3 Answers3

3

Try reproducing the symptom with another driver, like the HP LaserJet 4 or 4100 PCL. Use the built-in driver, not a custom driver that is supplied by the vendor.

If the symptom occurs with those drivers, it is probably not an issue with the P4515 driver.

Run a find on your %systemroot%\system32\spool\drivers folder, searching for hpbmini.dll and hpcdmc32.dll. Older versions of these files are known to cause major issues in printing.

Greg Askew
  • 34,339
  • 3
  • 52
  • 81
  • How old is too old? of hpbmini.dll there are versions 1.0.0.19 and 1.0.0.12. Of hpcdmc32.dll there are versions 1.0.2.37 and 1.0.1.17. – mpeterson Oct 15 '09 at 15:24
  • hpbmini.dll 1.0.0.18 and later should be ok. Not sure about hpcdmc32.dll. Generally speaking, if you are using a custom (not built-in) HP driver, I would update these files or the entire driver package and re-test, along with testing with a built-in driver. – Greg Askew Oct 15 '09 at 15:44
  • I've marked this as the answer because the printer servers were rebuilt (unrelated to this issue) and I've not had the problem anymore. My guess is that one of the PCL6 drivers I had narrowed down was buggy, and when they rebuilt the server they used a different version. – mpeterson Feb 17 '10 at 04:37
2

Your are Dispose()-ing of your PrintDocument objects are you? This is a frequent omission from MS .NET examples.

Maximus Minimus
  • 8,937
  • 1
  • 22
  • 36
  • To be honest, no, I haven't changed that. However there is no Dispose method explicitly defined on that object; it inherits the Dispose method from Component. That combined with the lack of an example in MSDN made me think it wasn't necessary? It shouldn't hurt anything, so I'll give that a try. Thanks for the suggestion. – mpeterson Oct 15 '09 at 15:07
  • As printing is a GDI task that will use unmanaged resources, always disposing is good practice anyway. It may be the case that PrintDocument spawns other class instances that require a Dispose which would be handled by the Dispose inherited from Component. – Maximus Minimus Oct 15 '09 at 16:40
  • I did ask this question on the MSDN forums, and the responses are somewhat mixed. There doesn't appear to be a reason NOT to dispose, but there also appears to be no reason to do so. You can read it here if so inclined: http://social.msdn.microsoft.com/Forums/en-US/csharpgeneral/thread/c011d546-5809-4b24-ac0f-9140e9425d00 – mpeterson Oct 15 '09 at 18:16
  • I would run with the advice in the last comment there: "if your class implements IDisposable, Dispose() it. Even when it's technically (currently) not meaningful to do so." The person who says it's OK to not Dispose() is playing with fire. Anyway, that aside, did you try it and did it work or not? – Maximus Minimus Oct 16 '09 at 08:16
  • I won't be able to try any of this until next week, but will update everyone with the results at that time. – mpeterson Oct 16 '09 at 16:07
1

Check the application code. Make sure printer connections are created inside of using statements. Otherwise managed code is not guaranteed to close them in a timely matter, and how fast things are release really could depend on the nature of the printer driver (meaning the different model printers could be a symptom of this deeper problem).

Joel Coel
  • 12,910
  • 13
  • 61
  • 99