PropertyGrid GDI handle leak in .NET 7.0
See original GitHub issue.NET version
dotnet --infosays 7.0.200.System.Runtime.InteropServices.RuntimeInformation.FrameworkDescriptionsays 7.0.3.
Did it work in .NET Framework?
Yes
Did it work in any of the earlier releases of .NET Core or .NET 5+?
.NET 5.0 and .NET 6.0.
Issue description
Using PropertyGrid will leak GDI objects whenever PropertyGridView’s OnPaint gets called.
Using reflection API…
- Setting Visible=false for
_commandsPanemade no difference. - Setting Visible=false for
_helpPanemade no difference. - Setting Visible=false for
_gridViewstopped the leak.
Using different framework versions…
- Using
.NET 5.0stopped the leak. (.NET 5.0.17) - Using
.NET 6.0stopped the leak. (.NET 6.0.14) - Using
.NET 7.0has the leak. (.NET 7.0.3)
Steps to reproduce
- Open Windows Task Manager, go to Details tab, and enable “GDI objects” column in the list view.
- Run the program with Target framework set as
.NET 5.0, and see how “GDI objects” stays around 70 when you resize the window. - Run the program with Target framework set as
.NET 6.0, and see how “GDI objects” stays around 80 to 90 when you resize the window. - Run the program with Target framework set as
.NET 7.0, and see how “GDI objects” skyrockets when you resize the window, and once it reaches 9,999, it starts to fail to draw, and soon crash.
using System;
using System.Windows.Forms;
class Program {
[STAThread]
static void Main() {
var pg = new PropertyGrid() {
Anchor = AnchorStyles.Left | AnchorStyles.Top,
Dock = DockStyle.Fill,
};
var form = new Form {
Controls = { pg },
};
pg.SelectedObject = form;
Console.WriteLine(System.Runtime.InteropServices.RuntimeInformation.FrameworkDescription);
Application.Run(form);
}
}
Issue Analytics
- State:
- Created 5 months ago
- Reactions:1
- Comments:7 (4 by maintainers)
Top Results From Across the Web
[main] Update dependencies from dotnet/arcade (#9027)
NET UI framework for building Windows desktop applications. ... PropertyGrid GDI handle leak in .NET 7.0 #6284. Sign in to view logs ·...
Read more >GDI/User Object Leak Tracking – The Easy Way - Alois Kraus
One of the most complex issues are User/GDI object leaks because they are nearly invisible in memory dumps. Microsoft does not want us...
Read more >c# - GDI-Handle Leak
I solved the problem. On the system I got the bug I ran the tool "GDIView". With this tool I was able to...
Read more >GDI Leaks: How to identify and fix them?
One leaked object per operation becomes a big leak. The second rule is: if a GDI object is selected to a device context,...
Read more >What's New in v21.2 | DevExpress
UI controls (Grid, TreeList, and Breadcrumb editor) are pre-customized via extensions - objects similar to WinForms Behaviors.
Read more >
Top Related Medium Post
No results found
Top Related StackOverflow Question
No results found
Troubleshoot Live Code
Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free
Top Related Reddit Thread
No results found
Top Related Hackernoon Post
No results found
Top Related Tweet
No results found
Top Related Dev.to Post
No results found
Top Related Hashnode Post
No results found

Reopening for 7.0 servicing.
@elachlan we can repro this issue on .NET 7.0 & 8.0, as @Soreepeong said, after resizing the form window, and once it reaches 9,999, it starts to fail to draw, and soon crash. When targeting to .NET 6.0, “GDI objects” stays around 60 to 80 when resizing form window. When targeting to .NET 5.0, “GDI objects” stays around 60 to 70 when resizing form window.
Call Stack: System.Runtime.InteropServices.ExternalException HResult=0x80004005 Message=A generic error occurred in GDI+. Source=System.Drawing.Common StackTrace: at System.Drawing.Graphics.CheckErrorStatus(Int32 status) at System.Drawing.Graphics.DrawString(String s, Font font, Brush brush, RectangleF layoutRectangle, StringFormat format) at System.Windows.Forms.Label.OnPaint(PaintEventArgs e) at System.Windows.Forms.Control.PaintWithErrorHandling(PaintEventArgs e, Int16 layer) at System.Windows.Forms.Control.WmPaint(Message& m) at System.Windows.Forms.Control.WndProc(Message& m) at System.Windows.Forms.Label.WndProc(Message& m) at System.Windows.Forms.Control.ControlNativeWindow.WndProc(Message& m) at System.Windows.Forms.NativeWindow.Callback(HWND hWnd, WM msg, WPARAM wparam, LPARAM lparam)