73

I am getting this warning from FxCop:

"'RestartForm' contains field 'RestartForm.done' that is of IDisposable type: 'ManualResetEvent'. Change the Dispose method on 'RestartForm' to call Dispose or Close on this field."

Ok, I understand what this means and why this is what needs to be done... Except System.Windows.Forms.Form doesn't allow you to override either .Close() or .Dispose(), so what to do? Currently I'm running with this solution:

    private void RestartForm_FormClosing(object sender, FormClosingEventArgs e)
    {
        done.Set();
        done.Close();
    }

Which works as intended for my application... But FxCop still shows this message. Am I covered and can I safely ignore it, or is there another way I should be doing this?

Matthew Scharley
  • 127,823
  • 52
  • 194
  • 222
  • 5
    You can also subscribe to Disposed event in your constructor, if you do not want to touch designer generated code. – arbiter Jun 27 '09 at 10:38

4 Answers4

133

You need to override the Dispose method from Form

Typically this is automatically overridden in the RestartForm.Designer.cs file, so you will need to move the dispose into your code file so that you can add whatever code you need to add without it being rewritten by the designer.

In the RestartForm.cs

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

    // Dispose stuff here
  }

  base.Dispose(disposing);
}
Derek W
  • 9,708
  • 5
  • 58
  • 67
heavyd
  • 17,303
  • 5
  • 56
  • 74
  • 6
    This is exactly what I was missing... I didn't even think to check if the designer was putting it in it's autogenerated code... Explains why it wasn't on the override list, it was already implemented, just not by me! – Matthew Scharley Jun 27 '09 at 06:16
  • Where do I put my dispose stuff in case `disposing` and `components != null` are evaluated at the same line? Eg. `if (disposing && (components != null))` (default for vs2013) – first timer May 06 '15 at 13:54
  • 1
    @firsttimer, the logic is the same. You need to move the method out of your designer file and then break up the conditions. your code should look like my example above when you're done. – heavyd May 06 '15 at 14:04
9

I use this method :)

            Image bgImage = Image.FromFile(workingDir + "\\" + button.BackgroundImage);
            currentButton.Image = bgImage;
            currentButton.Disposed += (Object sndr, EventArgs evnt) => bgImage.Dispose();
AlexTheo
  • 4,004
  • 1
  • 21
  • 35
  • Doesn't this just leave you with an event sink to unsubscribe from, leaving you open to a resource leak since you've already disposed the form? – IAmJersh Jun 07 '18 at 11:55
  • No, it doesn't matter. It will be untied automatically if the subscribed class doesn't have another running class tied to it. – qckmini6 Aug 29 '20 at 13:48
2

If RestartForm extends System.Windows.Forms.Form, you should be able to override Dispose(bool disposing). You should properly implement this for your "RestartForm" class to dispose of your IDisposables.

It should look like:

public override Dispose(bool disposing)
{
   if (disposing)
   {
       // Dispose was called from user code. Dispose of managed resources here.
       done.Dispose();
   }

   // Dispose of unmanaged resources here, and invoke base dispose.
   base.Dispose(disposing);
}
womp
  • 115,835
  • 26
  • 236
  • 269
  • it's `public override *void* Dispose(bool disposing) { ... }`. Don't add the asterisks, they are there for emphasis that `void` is missing. – Andy Oct 26 '22 at 00:19
0

You need to override the Dispose method, this method comes from the Control base class

protected override void Dispose(bool disposing)
{
  if (disposing)
  {
    event.Dispose();
  }
  base.Dispose(disposing);
}
Shay Erlichmen
  • 31,691
  • 7
  • 68
  • 87