I have created a custom control like below.

 public partial class TextBoxEx : TextBox
{
  public TextBoxEx()
  {
    InitializeComponent();
    Font = Utility.normalFont;
  }

protected override void OnPaint(PaintEventArgs pe)
{
    base.OnPaint(pe);
 }
}
//A utility class to initialize font.   
class Utility
{

    internal static Font normalFont = new Font("Arial", 18);
}

I have two forms Form1 and Form2. This TextBoxEx is added to Form2. I am showing Form2 when clicking a button in Form1.

Continuously showing and closing Form2 causes GDI leak in my application. After analysing with a GDI detection tool(Bear.exe), it is found that the Font causes GDI leak.

My question is,
1. Why the Font is not released even though Dispose() method of TextBoxEx is get called.(While closing Form2, Dispose() method of TextBoxEx will be invoked automatically).
2. How can I solve GDI leak caused by Font?.
(Font.Dispose() cannot be called in Dispose() method of TextBoxEx. Because it throws "Parameter is not valid" exception in the constructor).

Recommended Answers

All 4 Replies

Try setting Font = null; in the Dispose method of TextBoxEx. I don't see anything here that would cause a GDI leak.

If you're using ShowDialog to display the form and not Disposing after returning, this will cause a memory leak:

public DialogResult StartForm()
{
    MyForm form = new MyForm();
    // Memory Leak
    return form.ShowDialog();
}

public DialogResult StartForm_Safe()
{
    using(MyForm form = new MyForm())
    {
        DialogResult result = form.ShowDialog();
        return result;
    }
}

Other than that, I agree with Momerath, can't see anything obvious that will leak.

When I continuously open and close Form2, GDI count in TaskManager keeps increasing by 1.
After increasing the GDI count to some point(Say 70-80), it will automatically decreases to some count(Say 30-40) and so on.

when setting Font=null in Dispose() method of TextBoxEx,GDI count in TaskManagerwill be reset to 4 while closing the Form.

 protected override void Dispose( bool disposing ) 
 {
      if( disposing )
      {
         if (components != null) {
           components.Dispose();
          }
      }
     base.Dispose( disposing );
     Font=null;
}

Is it recommended to set Font as NULL in Dispose() method of TextBox control Or Should I ignore it and let the Font to get garbage collected ?

I've done a bit of reading and it appears that Font is not a managed object and so it should be disposed.

In order to facilitate this, create a FontHelper (much like your static method) that returns a new font on every request. This will allow you to dispose the Font object when you close your form. As Font is an unmanaged object (implementing IDisposable) you must dispose the font object when you're disposing your form.

Once you've disposed it, setting it to null should be unnecessary.

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.