bRaNdOn
bRaNdOn

Reputation: 1082

How to Create a Disposable class

I have this 'PlayerClass' class and every time I instantiate it I need to dispose of it, including the fields inside that class. Is there a way to do it? This is my class:

internal class PlayerClass 
{
    public WindowsMediaPlayer _wplayer;
}

How do I get to dispose of the class after using it? I have tried to find a way on the internet but none of them are working after testing it.

I've tried this:

internal class PlayerClass : IDisposable
{
    public WindowsMediaPlayer _wplayer;
    public void Dispose()
    {
        Dispose(true);
        GC.SuppressFinalize(this);
    }
    
    /// <summary>
    /// Is this instance disposed?
    /// </summary>
    protected bool Disposed { get; private set; }
    
    /// <summary>
    /// Dispose worker method. See http://coding.abel.nu/2012/01/disposable
    /// </summary>
    /// <param name="disposing">Are we disposing? 
    /// Otherwise we're finalizing.</param>
    protected virtual void Dispose(bool disposing)
    {
        Disposed = true;
    }
}

What am I doing wrong?

Upvotes: 5

Views: 25747

Answers (3)

Timeout
Timeout

Reputation: 7909

It looks as if you're implementing IDisposable just for the heck of it which is not necessary for managed code. The garbage collector will automatically clean up behind you.

You may need to clarify in your post why you are implementing IDisposable.

However I believe your mistake is that Dispose() is not automatically called by the garbage collector. If you do implement IDisposable you must make sure that the code using your class either instantiates inside a using() statement or manually calls .Dispose. Otherwise your dispose method will never fire.

using(var player = new PlayerClass()){
    // Do something with player
    // player.Dispose() is called automatically when you exit this using statement.
}

Since you're relying on the caller to make sure Dispose is called you may also want to look into a SafeHandle (preferred) or Finalize.

Because the IDisposable.Dispose implementation is called by the consumer of a type when the resources owned by an instance are no longer needed, you should either wrap the managed object in a SafeHandle (the recommended alternative), or you should override Object.Finalize to free unmanaged resources in the event that the consumer forgets to call Dispose.

Source: IDisposable Interface

Using Statement https://learn.microsoft.com/en-us/dotnet/csharp/language-reference/keywords/using-statement

Upvotes: 5

Pieter Geerkens
Pieter Geerkens

Reputation: 11893

Contrary to the advice of the other answers, it is necessary and essential to Dispose of all created objects that implement a Dispose() method (ie implement IDisposable). These objects are unmanaged resources, and thus are invisible to the GC. Not disposing of them is a guaranteed memory leak.(Note that some terminology prefers a Close() method to a Dispose method, in which case the Close() method should be identical.)

Here is a best practice implementation of the IDisposable interface.

#region IDisposable implementation with finalizer
private bool isDisposed = false;
public void Dispose() { Dispose(true); GC.SuppressFinalize(this); }
protected virtual void Dispose(bool disposing) {
  if (!isDisposed) {
    if (disposing) {
      if (_wplayer != null)     _wplayer.Dispose();
   }
  }
  isDisposed = true;
}
#endregion

Here are the Best Practices Dos and Donts from the MSDN link above:

  • DO declare a protected virtual void Dispose(bool disposing) method to centralize all logic related to releasing unmanaged resources.
  • DO implement the IDisposable interface by simply calling Dispose(true) followed by GC.SuppressFinalize(this).
  • DO NOT make the parameterless Dispose method virtual.
  • DO NOT declare any overloads of the Dispose method other than Dispose() and Dispose(bool).
  • DO allow the Dispose(bool) method to be called more than once. The method might choose to do nothing after the first call.
  • AVOID throwing an exception from within Dispose(bool) except under critical situations where the containing process has been corrupted (leaks, inconsistent shared state, etc.).
  • CONSIDER providing method Close(), in addition to the Dispose(), if close is standard terminology in the area.

Upvotes: 4

Felipe Oriani
Felipe Oriani

Reputation: 38608

From the MSDN documentation.

Provides a mechanism for releasing unmanaged resources.

You do not need to dispose managed objects. .Net will lead with this for you. It is usefull when you create a interop classes which will lead with unmanaged resources, then you can dispose all objects.

Upvotes: 0

Related Questions