4

I often used the disposable pattern in simple classes that referenced small amount of resources, but I never had to implement this pattern on a class that inherits from another disposable class and I am starting to be a bit confused in how to free the whole resources.

I start with a little sample code:

public class Tracer : IDisposable
{
 bool disposed;
 FileStream fileStream;
 public Tracer()
 {
 //Some fileStream initialization
 }
 public void Dispose()
 {
 this.Dispose(true);
 GC.SuppressFinalize(this);
 }
 protected virtual void Dispose(bool disposing)
 {
 if (!disposed)
 {
 if (disposing)
 {
 if (fileStream != null)
 {
 fileStream.Dispose();
 } 
 }
 disposed = true; 
 }
 }
}
public class ServiceWrapper : Tracer
{
 bool disposed;
 ServiceHost serviceHost;
 //Some properties
 public ServiceWrapper ()
 {
 //Some serviceHost initialization
 }
 //protected override void Dispose(bool disposing)
 //{
 // if (!disposed)
 // {
 // if (disposing)
 // {
 // if (serviceHost != null)
 // {
 // serviceHost.Close();
 // } 
 // }
 // disposed = true;
 // }
 //}
}

My real question is: how to implement the disposable pattern inside my ServiceWrapper class to be sure that when I will dispose an instance of it, it will dispose resources in both inherited and base class?

Thanks.

asked Apr 3, 2010 at 15:01

4 Answers 4

3

I have seen this done a couple of ways:

  1. In the derived class override Dispose(bool disposing), cleanup your stuff and then call the base class Dispose(bool disposing). The problem here is the base class already has the disposed gate variable and checks that would would need to be replicated.

  2. Create a protected Cleanup method that Dispose(bool disposing) in the base class calls to actually do the cleanup. The derived class can override it, do it's cleanup, and call the base class Cleanup method. This leaves all of the disposed checks in the base class that don't have to be replicated.

answered Apr 3, 2010 at 15:10
Sign up to request clarification or add additional context in comments.

2 Comments

The first solution seems great but many guidelines warn about this kind of usage. The disposing boolean purposes is to inform that the disposing has been called from the Dispose() method. Here, we cannot say it is not the case, but this is done inderectly.
I finally found a CodeAnalysis rule which was defining a precise guideline for this kind of situation : msdn.microsoft.com/fr-fr/library/ms182330(VS.80).aspx This guideline exactly matches your first solution.
2

You have some problems firstly you don't define a finalizer yet you call GC.Suppressfinalizer. also you set disposed in the wrong method and on top of that your dispose isn't thread safe.

I use a base disposed class that implements IDispose along with a while host of other helper methods.

public class Disposable : IDisposable
{
 private object _lock = new object();
 ~Disposable()
 {
 try
 {
 Dispose(false);
 }
 catch
 {
 }
 }
 protected void ThrowIfDisposed()
 {
 if (IsDisposed)
 {
 throw new ObjectDisposedException(GetType().FullName);
 }
 }
 public bool IsDisposed { get; private set; }
 protected virtual void Dispose(bool disposing)
 {
 }
 public void Dispose()
 {
 lock (_lock)
 {
 if (!IsDisposed)
 {
 Dispose(true);
 IsDisposed = true;
 GC.SuppressFinalize(this);
 }
 }
 }
}
answered Jan 26, 2011 at 21:50

Comments

1

Have a look at this blog post by Davy Brion: http://davybrion.com/blog/2008/06/disposing-of-the-idisposable-implementation/

It adds a little extra code to the parent class, but doing appropriate cleanup in the subclass becomes rather simple.

answered Apr 3, 2010 at 18:45

1 Comment

Thanks for this article. It is a great illustration of the second solution proposed by daddyman. I think I will chose this way the next time I will have to make disposable classes. It is so much easier to implement. Thanks again.
0

The inherited class, ServiceWrapper, inherits from a class that implements IDisposable, so SericeWrapper also implements IDisposable. For proof, new up an instance of ServiceWrapper. You'll find (with intellisense) that it too has a Dispose() method.

answered Apr 3, 2010 at 15:04

1 Comment

Yes I know that, but the problem is that it is gonna call the Dispose(bool disposing) method inside the ServiceWrapper class and therefore will not free resources in my base class. And if I call base.Dispose() method at disposing in the inherited class, I am gonna have a stack overflow problem.

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

By clicking "Post Your Answer", you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.