I've got a C# project that calls into a 3rd party unmanaged DLL for controlling a PCI card. Their API documentation states that a call to CardClose must be made before my application terminates. Because the card is multifunctional, I've written two interfaces for it and implemented them using separate singleton classes. There is also a base class for sharing common information, such as the CardHandle, and for generating the singleton instances (factory pattern).
My challenge is figuring out how to use finalizers in the subclasses to call CardClose when the class is disposed. But I only want that to happen when both classes have been disposed, otherwise the card becomes unavailable to the other class that is still using it. (I realize you wouldn't normally dispose of a singleton, but I have reasons for doing so in this case.) One solution is to combine these classes into one, but I'm curious if there's a better way.
Here's the dispose code for the base class:
protected static int CardHandle { get; set; } = -1;
protected static bool IsAvailable { get; set; } = false;
protected static uint InstancesCount { get; private set; } = 0;
#region IDisposable Support
private bool m_alreadyDisposed = false; // To detect redundant calls
protected virtual void Dispose(bool disposing) // Overridden by subclasses which should then call base.Dispose(disposing)
{
if (m_alreadyDisposed) return;
if (disposing)
{
// Dispose managed state (managed objects).
}
// Free unmanaged resources (unmanaged objects) and override a finalizer below.
InstancesCount--;
m_alreadyDisposed = true;
}
// Override a finalizer only if Dispose(bool disposing) above has code to free unmanaged resources.
//~Arinc()
//{
// // Do not change this code. Put cleanup code in Dispose(bool disposing) above.
// Dispose(false);
//}
public void Dispose()
{
// Put cleanup code in Dispose(bool disposing) above.
Dispose(true); // When overriden, this will call the derived class's Dispose(boolean).
GC.SuppressFinalize(this);
}
#endregion
First subclass with finalizer:
#region IDisposable Support
private bool m_alreadyDisposed = false; // To detect redundant calls
protected override void Dispose(bool disposing)
{
if (m_alreadyDisposed) return;
if (disposing)
{
// Dispose managed state (managed objects).
Arinc429Device = null; // This class instance, stored as a property.
}
// Free unmanaged resources (unmanaged objects) and override a finalizer below.
if (InstancesCount == 1) // This is the last instance if true.
{
L43_CardReset(CardHandle); // Unmanaged code call.
L43_CardClose(CardHandle); // Unmanaged code call.
CardHandle = -1;
IsAvailable = false;
}
m_alreadyDisposed = true;
base.Dispose(disposing);
}
~Arinc429Ballard()
{
// Do not change this code. Put cleanup code in Dispose(bool disposing) above.
Dispose(false);
}
#endregion
The second subclass uses the same dispose code but with a different instance property. As you can see, I'm attempting to keep track of the total instances count using the InstancesCount property which is incremented by the factory. When the last instance is disposed, the card is closed, but this approach is proving to be less than reliable.
Related
I am trying to implement the IDisposable pattern on a derived class, and it's not working as expecting to work,
Suppose I have two classes and I want to call the Dispose method of the derived class:
Below is the code of my base class
public class BaseClass : IDisposable
{
// To detect redundant calls
private bool _disposedValue;
// Public implementation of Dispose pattern callable by consumers.
public void Dispose()
{
Dispose(true);
GC.SuppressFinalize(this);
}
// Protected implementation of Dispose pattern.
protected virtual void Dispose(bool disposing)
{
if (!_disposedValue)
{
if (disposing)
{
// TODO: dispose managed state (managed objects)
}
// TODO: free unmanaged resources (unmanaged objects) and override finalizer
// TODO: set large fields to null
_disposedValue = true;
}
}
}
And I've something like this as a derived class
public class DerivedClass : BaseClass
{
// To detect redundant calls
private bool _disposedValue;
// Protected implementation of Dispose pattern.
protected override void Dispose(bool disposing)
{
if (!_disposedValue)
{
if (disposing)
{
}
_disposedValue = true;
}
// Call base class implementation.
base.Dispose(disposing);
}
}
And I've some wrapper class
public class WrapperClass : IDisposable
{
public ReadOnlyCollection<BaseClass> Items { get; set;}
// To detect redundant calls
private bool _disposedValue;
// Public implementation of Dispose pattern callable by consumers.
public void Dispose()
{
Dispose(true);
GC.SuppressFinalize(this);
}
// Protected implementation of Dispose pattern.
protected virtual void Dispose(bool disposing)
{
if (!_disposedValue)
{
if (disposing)
{
foreach (var item in Items)
{
item.Dispose();
}
}
_disposedValue = true;
}
}
}
My issue is in the wrapper class, it doesn't call the Dispose method of the DerivedClass, and it calls the Dispose method of the BaseClass instead.
Update
It's my bad, I forget to say that the collections of items were created by NSubstitute like below:
// Having this will not call the Dispose method of the derived class
Items = new ReadOnlyCollection<BaseClass>(new List<BaseClass>
{
Substitute.For<DerivedClass>()
})
// Having this will call the Dispose method of the derived class
Items = new ReadOnlyCollection<BaseClass>(new List<BaseClass>
{
new DerivedClass>()
})
The public implementation of the Dispose() pattern in the documentation is there as an example to handle every case and contingency. It's always "safe" to do the whole thing, but it's also true that most of the time you can skip most of the pattern.
Especially regarding finalizers: you should only need a finalizer if you are creating an original wrapper implementation for a brand new kind of unmanaged resource. Each unmanaged resource type only needs one finalizer, at the root of the IDisposable inheritance tree. And if you don't add a finalizer, you don't need to worry about GC.SuppressFinalize(). Remove that, and some other balls drop as well.
In short, we can reduce the pattern for your DerivedClass all the way down to this:
public class DerivedClass : BaseClass
{
}
This DerivedClass type still provides the Dispose() method and IDisposable implementation inherited from it's parent, and if it doesn't introduce any other unmanaged resources that's all it needs.
My issue is in the wrapper class, it doesn't call the Dispose method of the DerivedClass, and it calls the Dispose method of the BaseClass instead.
When the base.Dispose() calls Dispose(true) the method override in the derived class is executed, which in turn will call base. Dispose(true).
DerivedClass doesn't appear to override Dispose(). Consequently, the base class version is invoked.
Add a public void Dispose() method that calls your protected void Dispose(bool disposing) implementation in DerivedClass.
I have this question :
I can't understand why the second choice is the answer . I mean other methods ( KeepAlive and CancelFullGCNotification) will prevent system to call the finalizer.
What are the differences between the four methods?
In which cases, we have to use it?
The KeepAlive will only delay the finalizer being called on a class (by making the object live longer and not having it be eligible for finalization) and CancelFullGCNotification has nothing to do with finalizing.
Only SuppressFinialize will prevent the finalizer from running on a class.
The use of SuppressFinalizer is only necessary when you have coded a finalizer. Most of the time you would not need to suppress. Anyway, B is correct answer and the only way to prevent the destructor/finalize method from being called.
More importantly... the finalizer should rarely ever be used and delays garbage collection by itself.
It's there to clean up unmanaged resources and this is the pattern typically used:
public class SomeClass : IDisposable
{
private bool disposed;
//disposing is true if you're disposing managed resources
protected virtual void Dispose(bool disposing)
{
if (!disposed)
{
if (disposing)
{
//Dispose managed resources
}
//Dispose unmanaged resources
disposed = true;
}
}
public void Dispose()
{
Dispose(true);
GC.SuppressFinalize(this);
}
~SomeClass()
{
Dispose(false);
}
}
EDIT: To eager editors, please read the FULL question In addition, since this question is not only about disposing.
So far I've seen this:
protected override Dispose(bool disposing)
{
base.Dispose(disposing);
if (disposing)
c.Dispose()
}
and this:
protected virtual void Dispose(bool disposing)
{
if (!disposed)
{
if (disposing)
{
// Dispose managed resources.
}
// There are no unmanaged resources to release, but
// if we add them, they need to be released here.
}
disposed = true;
// If it is available, make the call to the
// base class's Dispose(Boolean) method
base.Dispose(disposing);
}
And Microsoft says CA2215: Dispose methods should call base class dispose, here. In addition, since this question is not only about disposing, here is another example from Microsoft calling base at the last line.
Which one is the correct/most common/better if any?
Your second snippet is doubtful, depending on whether disposed is a protected field from the base class or not.
protected virtual void Dispose(bool disposing)
{
if (!disposed)
{
if (disposing)
{
// Dispose managed resources.
}
}
disposed = true;
base.Dispose(disposing); // wrong if base.Disposing() depends on disposed
}
The issues to consider are exceptions and dependencies between base and derived class. So use a try/finally and put the base call last. The most general pattern would look like:
protected virtual void Dispose(bool disposing)
{
if (!disposed)
{
if (disposing)
{
// Dispose managed resources.
}
}
base.Dispose(disposing);
disposed = true; // inherited or local field
}
It's all about sequence of calls or control-flow, if you wish.
In first example dispose of base class base.Dispose() is called for first and after executed the code of the class itself. In second case, instead, vice versa.
So both of them are correct from behavior point of view, and you have to pick that one which fits best your current requirement, it can vary in the same program in regard of type naturally.
Forgive me in advance if this question is a little too open-ended, but I've seen similar language discussion posts here so I figured I'd take the plunge.
Anyway, I have read several MSDN help pages and various other blogs on the subject of properly implementing IDisposable classes. I feel like I understand things pretty well, but I have to wonder if there's a flaw in the suggested class structure:
public class DisposableBase : IDisposable
{
private bool mDisposed;
~DisposableBase()
{
Dispose(false);
}
public void Dispose()
{
Dispose(true);
GC.SuppressFinalize(this);
}
protected virtual void Dispose(bool disposing)
{
if (!mDisposed)
{
if (disposing)
{
// Dispose managed resources
mManagedObject.Dispose();
}
// Dispose unmanaged resources
CloseHandle(mUnmanagedHandle);
mUnmanagedHandle = IntPtr.Zero;
mDisposed = true;
}
}
}
Anytime the above is supposed to serve as a base class, you rely on the implementer of the subclass to properly override the Dispose(bool) method where necessary. In short, derived classes must ensure they invoke the base Dispose(bool) method from within their overridden version. If not, the base class' unmanaged resources may never get freed, defeating the primary purpose of the IDisposable interface.
We all know the benefits of virtual methods, but it seems like in this case their design falls short. In fact, I think this particular shortcoming of virtual methods manifests itself frequently when trying to design visual components and similar base/derived class structures.
Consider the following change, using a protected event rather than a protected virtual method:
public class DisposeEventArgs : EventArgs
{
public bool Disposing { get; protected set; }
public DisposeEventArgs(bool disposing)
{
Disposing = disposing;
}
}
public class DisposableBase : IDisposable
{
private bool mDisposed;
protected event EventHandler<DisposeEventArgs> Disposing;
~DisposableBase()
{
Dispose(false);
}
public void Dispose()
{
Dispose(true);
GC.SuppressFinalize(this);
}
// This method is now private rather than protected virtual
private void Dispose(bool disposing)
{
if (!mDisposed)
{
// Allow subclasses to react to disposing event
AtDisposing(new DisposeEventArgs(disposing));
if (disposing)
{
// Dispose managed resources
mManagedObject.Dispose();
}
// Dispose unmanaged resources
CloseHandle(mUnmanagedHandle);
mUnmanagedHandle = IntPtr.Zero;
mDisposed = true;
}
}
private void AtDisposing(DisposeEventArgs args)
{
try
{
EventHandler<DisposeEventArgs> handler = Disposing;
if (handler != null) handler(this, args);
}
catch
{
}
}
}
With this design, the base class' Dispose(bool) method will always be called, regardless of whether subclasses subscribe to the Disposing event or not. The biggest flaw that I can see with this revised setup is that there is no predetermined order for when event listeners are called. This could be problematic if there are multiple levels of inheritance, e.g. SubclassA's listener might be triggered before its child SubclassB's listener. Is this flaw serious enough to invalidate my revised design?
This design dilemma makes me wish there were some sort of modifier for methods that was similar to virtual but which would ensure that the base class' method was always called, even if a subclass overrode that function. If there's a better way to achieve this, I would greatly appreciate your suggestions.
You're using an event here when really you want to use an inheritance mechanism like virtual. For scenarios like this where I want to ensure my implementation is always called but want to allow for base class customization I use the following pattern
private void Dispose(bool disposing)
if (mDisposed) {
return;
}
if (disposing) {
mManagedObject.Dispose();
}
// Dispose unmanaged resources
CloseHandle(mUnmanagedHandle);
mUnmanagedHandle = IntPtr.Zero;
mDisposed = true;
DisposeCore(disposing);
}
protected virtual void DisposeCore(bool disposing) {
// Do nothing by default
}
With this pattern I've ensured my base class Dispose implementation will always be called. Derived classes can't stop me by simply forgetting to call a base method. They can still opt into the dispose pattern by overriding DisposeCore but they can't break the base class contract.
The derived class can simply re-implement IDisposable and thus prevent your dispose method from being called, so you can't ensure that either.
Personally I wouldn't use either pattern. I prefer building on SafeHandle and similar mechanisms, instead of implementing finalizers myself.
Consider making it apparent that Dispose is not being called so someone will catch it. Of course Debug.WriteLine will only be called when the code is compiled with DEBUG compiler directive defined.
public class DisposableBase : IDisposable
{
private bool mDisposed;
~DisposableBase()
{
if (!mDisposed)
System.Diagnostics.Debug.WriteLine ("Object not disposed: " + this + "(" + GetHashCode() + ")";
Dispose(false);
}
public void Dispose()
{
Dispose(true);
GC.SuppressFinalize(this);
}
You can break it down:
A destructor (finalizer) is only needed for unmanaged resources.
Using a Safehandle can turn an unmanged resource into a managed resource.
Ergo: You won't need a destructor. That halves the Dispose pattern.
The reference design uses a virtual void Dispose(bool) to cater for the Base/Derived class problem. This puts the burden on the derived class to call base.Dispose(disposing), the core of your question. I use 2 approaches:
1) Prevent it. With a sealed base-class you won't have to worry.
sealed class Foo:IDisposable
{
void Dispose() { _member.Dispose(); }
}
2) Check it. Like #j-agent's answer but conditional. When performance could be an issue then you don't want the finalizers in Production code:
class Foo:IDisposable
{
void Dispose() { Dispose(true); }
[Conditional("TEST")] // or "DEBUG"
~Foo { throw new InvalidOperation("somebody forgot to Dispose") }
}
The destructor is going to be called no matter if any subclass overrides Dispose() (can be via override or new) but your destructor is going to be called ( ~DisposableBase() ) so i bet putting your logic for cleanup there can be a good starting point.
Here is an intersting article about destructors: http://www.c-sharpcorner.com/UploadFile/chandrahundigam/UnderstandingDestructors11192005021208AM/UnderstandingDestructors.aspx
If a class has a property which contains unmanaged resources. How to make sure no memory leak when using the class
Class A
{
B {get; set;}
}
B contains unmanaged resources.
Implement IDisposable and clean up your unmanaged resources by calling Dispose(), preferably placing the call to Dispose in a finally statement so you clean up resources even in the case of an exception.
C# has a using keyword that you can employ to make sure that the Dispose method is called, even if an exception is thrown.
EDIT: Incorporated call to GC.SuppressFinalize and finalizer implementation per Ran's answer
class A : IDisposable
{
private bool _disposed;
~A()
{
this.Dispose(false);
}
public void Dispose()
{
this.Dispose(true);
GC.SuppressFinalize(this);
}
protected virtual void Dispose(bool disposing)
{
if (!_disposed)
{
if (disposing)
{
// dispose managed resources
}
// clean up unmanaged resources
_disposed = true;
}
}
}
class Program
{
static void Main(string[] args)
{
using (var someInstance = new A())
{
// do some things with the class.
// once the using block completes, Dispose
// someInstance.Dispose() will automatically
// be called
}
}
}
Using IDisposable might not be enough, because it relies on the user remembering to call Dispose or to use using etc.
For a complete solution, combine IDisposable and a finalizer. Like this:
Edit: Made some corrections in the Dispose method based on SpeksETC's comment.
class MyClass : IDisposable
{
~MyClass()
{
Dispose(false);
}
public void Dispose()
{
GC.SupressFinalize();
Dispose(true);
}
protected virtual void Dispose(bool disposing)
{
if (!disposing)
{
// clear unmanaged resources here (can only be called once)
...
}
// dispose called explicitly by the user, clean up managed resources here
...
}
}
This ensures that native resources will always be cleared, even if the user forgets to call Dispose, while still allowing the user to clear the resources early.
The if inside the Dispose implementation is needed because if this class is being finalized, you may not call Dispose on your members because they may have been GC'ed already.
I think it is important to point out that B is a managed resource that only contains unmanaged resources.
Therefore, A should implement IDisposable and dispose of B in its Dispose() method, but does not need a finalizer since it doesn't have any unmanaged resources to clean up - the finalizer needs to be implemented within B itself. Even if you implemented a finalizer it would call a Dispose that looked like this:
protected virtual void Dispose(bool disposing)
{
if (disposing)
{
// dispose called explicitly by the user, clean up managed resources here
b.Dispose()
}
// no unmanaged resources to clean up so do nothing which makes Finalizer unneccesary
...
}
SpeksEtc is correct in that if B contains unmanaged resources then B should ensure there are no leaks not A.
But what are the unmanaged resources and would the SafeHandle class help? Then B would contain a SafeHandle which would contain the unmanaged resource and you wouldn't need to worry about it.