This is an example of a GDI handle leak when printing on some printers on Windows 10 Pro (20H2 - 19042.868). All printers have official drivers installed.
For example if I try this on one printer, lets say Printer A everything is fine and handles are getting disposed. GDI Handles go to 70 max and then drop to ~30 - no leak, when I run the exact same code but on Printer B GDI handles leak quickly to 10000 (max for a process), around 5000 BitMaps (observed with task manager and GDIView) and I get exception "A generic error occurred in GDI+."
Stack trace is:
at System.Drawing.Graphics.CheckErrorStatus(Int32 status)
at System.Drawing.Graphics.DrawString(String s, Font font, Brush brush, RectangleF layoutRectangle, StringFormat format)
at System.Drawing.Graphics.DrawString(String s, Font font, Brush brush, PointF point)
at DrawStringTests.SimplePrinter.printerDoc_PrintPage(Object sender, PrintPageEventArgs e) in c:\projects\TESTS\DrawStringTests\SimplePrinter.cs:line 38
.
//If there is a leak this will generate exception
for (int i = 0; i < 100; i++)
{
using (var simplePrinter = new SimplePrinter())
{
simplePrinter.Print("POSPRINTER");
}
}
class SimplePrinter : IDisposable
{
Font _font;
Brush _brush;
PrintDocument printerDoc;
public SimplePrinter()
{
_font = new Font("Consolas", 12);
_brush = new SolidBrush(Color.Black);
}
public void Print(string printerName)
{
printerDoc = new PrintDocument();
printerDoc.PrintPage += printerDoc_PrintPage;
printerDoc.PrinterSettings.PrinterName = printerName;
printerDoc.Print();
}
void printerDoc_PrintPage(object sender, PrintPageEventArgs e)
{
int y = 0;
for (int i = 0; i < 100; i++)
{
e.Graphics.DrawString("qwertzuiopšđasdfghjklčćžyxcvbnm", _font, _brush, new PointF(0, y));
y += (_font.Height + 1);
}
e.HasMorePages = false;
}
public void Dispose()
{
_font.Dispose();
_brush.Dispose();
printerDoc.PrintPage -= printerDoc_PrintPage;
printerDoc.Dispose();
}
}
Why is this happening only for some printers and not all of them? What am I doing wrong?