I have a .NET Framework Console app (4.6.2 and 4.7.2 exhibit this issue). It opens a SaveFileDialog
5 times in a row, each time waiting for the previous dialog to close.
Looking at the GDI column in TaskManager, I'm seeing the GDI object count start at 79, then go to 83, then 87, etc. It leaks 4 objects each time. This doesn't happen with an OpenFileDialog
or other CommonDialogs that I've tested.
I am disposing the object, and I don't see this issue with .NET Core 3.1 (I don't see the issue in my .NET Core 3.1 app, but in the minimal example below, I do see it in both .NET Core 3.1 and in .NET 6).
The GDIView tool shows this:
Handle | Object Type | Kernel Address | Detect Counter |
---|---|---|---|
0xbc041a92 | Region | 0xffffffffffbc1a92 | 1 |
0x8410215d | Brush | 0xffffffffff84215d | 1 |
0x811024af | Brush | 0xffffffffff8124af | 1 |
0x620433b1 | Region | 0xffffffffff6233b1 | 1 |
0x4a103550 | Brush | 0xffffffffff4a3550 | 1 |
0x8e043569 | Region | 0xffffffffff8e3569 | 1 |
0x35103a54 | Brush | 0xffffffffff353a54 | 1 |
0xda013d30 | DC | 0xffffffffffda3d30 | 1 |
0xdc043fc6 | Region | 0xffffffffffdc3fc6 | 1 |
C# code:
using System;
using System.Threading;
using System.Windows.Forms;
namespace GDILeakTest
{
internal class Program
{
[STAThread]
static void Main(string[] args)
{
for (int i = 0; i < 5; i++)
{
using (var dialog = new SaveFileDialog())
{
dialog.ShowDialog();
}
Thread.Sleep(5000);
}
}
}
}
Is this a known bug in .NET?
Update: two things that seems to address the leak (though interestingly enough, these don't help in my actual app).
- Adding an
Application.Run()
to the end of theMain
method - Removing
[STAThread]
and showing the dialog inside of an STA thread:
Thread t = new Thread(() =>
{
dialog.ShowDialog();
});
t.SetApartmentState(ApartmentState.STA);
t.Start();
t.Join();