Disposing objects (simplification) - c#

I found this code in Mono reimplementation of cryptographic transforms.
I didn't modify or simplify anything - this is how it actually goes (there are comments like // Dispose unmanaged objects, but nothing is actually done).
Now - the IDisposable-related code seems redundant to me. Can this somehow be simplified / removed completely without breaking something important?
public class ToBase64Transform : ICryptoTransform
{
private bool disposed;
~ToBase64Transform()
{
Dispose(false);
}
public void Clear()
{
Dispose(true);
}
void IDisposable.Dispose()
{
Dispose(true);
// Finalization is now unnecessary.
GC.SuppressFinalize(this);
}
protected virtual void Dispose(bool disposing)
{
if (disposed) return;
if (disposing)
{
}
disposed = true;
}
Full source is located here.

If it wraps unmanaged components, then that is the most appropriate implemntation.
If there aren't any unmanaged components, and it won't be subclassed, then yes; you can remove the finalizer and make it just have a simple Dispose():
public sealed class ToBase64Transform : ICryptoTransform
{
private bool disposed;
public void Dispose()
{
if (disposed) return;
// Dispose managed objects
disposed = true;
}
If there aren't any managed disposable components either, then ... just don't make it implement IDisposable.
I'm not sure I would expect a "Clear()" method to call "Dispose()", but maybe that is the norm in the context of crypto-streams.

A few points:
The public API that Mono expose must match the one provided by Microsoft or things will break. That includes finalizers (even when they are not needed by Mono). It's common for Mono to implement more stuff in managed code than Microsoft (actually very common in cryptography);
The type is not sealed so the Dispose(bool) method must be called (e.g. from the finalizer) nor abstract so the IDisposable interface must be implemented;
Mono comes with an extensive set of unit tests. When something looks weird it's a good idea to look at them. Matching MS implementation is not always straightforward and the MSDN documentation (while good and frequently updated) is not rarely enough or totally complete/right.
In this case the code inside Dispose(bool) is not required. I suspect it comes from a template (or from copy/pasting from another file) or the author was not sure if this code would move into unmanaged code in the future. Removing it is unlikely to change performance/size but fell free to submit a bug report (or pull request) to have it removed.

That's a completely standard way of implementing IDisposable. Agreed, no work is done, but if it has to be there for compatibility with MS.Net, then it's best done right.

A class which inherits from a base which implements IDisposable will generally need to ensure that a call to IDisposable.Dispose will call the base class' dispose logic as well as its own. This requires that at least one one of two conditions must apply:
There must be some means by which the derived class can ask to have derived-class Dispose logic called from the base class' implementation of IDisposable.Dispose(), without having to re-implement IDisposable.Dispose() itself.
If the derived class does re-implement IDisposable.Dispose, there must be some means by which the base class can expose its own disposed logic to the derived class, so the derived class' IDisposable.Dispose routine can call it.
There are a number of ways by which at least one of these conditions could be met; in different situations, different methods might be optimal. Most notably, for classes which have a public Dispose() method which will be semantically identical to IDisposable.Dispose(), it would be easiest to simply have the base class have a public virtual Dispose() method which implicitly implements IDisposable.Dispose. If a derived class overrides that method, it will override the behavior of IDisposable.Dispose, but its Dispose() can call base.Dispose() to activate the parent's dispose logic. This approach has one weakness, however: some class might not want to have a public Dispose() method which is semantically identical to IDisposable.Dispose(). While it might have been workable to use that approach for classes where it is suitable, and some other approach for other classes, Microsoft decided it would be better to have a common approach for all classes.
The idea is that all inheritable classes which implement IDisposable will have a protected virtual method whose signature doesn't match the possibly-public "void Dispose()"; IDisposable.Dispose() will call this method (with a parameter value of True) for all of its disposal logic, and a derived class which overrides this method may call the base disposal logic by calling the corresponding method of its parent. Although Microsoft allowed for the possiblity of a "Finalize" method calling this method with a value of false, there isn't really any need for that. Adding a Finalize method (or C# destructor) to a class which doesn't include all the provisions required for one--including "GC.KeepAlive() calls at key places) can be a breaking change which causes subtle bugs. If a class will need to use unmanaged resources but the parent class does not, that should be handled by defining new finalizable classes to encapsulate unmanaged resources into managed objects, and then have the inherited class hold those managed objects.

Related

Do I really need Basic dispose pattern for type referencing other IDisposable objects?

Microsoft design guidelines mention Dispose pattern and scenarios how to use it:
DO implement the Basic Dispose Pattern on types containing instances
of disposable types. See the Basic Dispose Pattern section for details
on the basic pattern.
Later, they show the Basic Dispose Pattern as follows:
public class DisposableResourceHolder : IDisposable {
private SafeHandle resource; // handle to a resource
public DisposableResourceHolder(){
this.resource = ... // allocates the resource
}
public void Dispose(){
Dispose(true);
GC.SuppressFinalize(this);
}
protected virtual void Dispose(bool disposing){
if (disposing){
if (resource!= null) resource.Dispose();
}
}
}
My questions are:
Why do we need to implement Dispose(bool) if it has just a single call with parameter true? It could be easily simplified to just parameterless Dispose() {resource?.Dispose();}. Note we don't need finalizer here because objects we are referencing are managed and have their own finalizers, so they won't be leaked.
Why do they recommend to call GC.SuppressFinalize(this) while not having finalizer? GC anyway wouldn't call finalizer because it does not exist!
The only case when I see the need of Dispose(bool) is when we really have some unmanaged references, which does not implement IDisposable nor finalizer (like shown in this article). But then the meaning of bool disposing would be bool includingManagedResources. So why is it named so misleading 'disposing' to what it should do in fact?
Other classes could inherit from your class. Considering that the deriving class also holds unmanaged resources (recommended or not), this class should then add the finalizer calling Dispose(false). If your class was sealed I would agree with you.
Because the method void Dispose() should not be virtual following the guidelines from Microsoft and thus deriving classes would then have no chance to suppress finalization after disposal. Your implementation might not need a finalizer, but probably deriving classes do.
It's called disposing for no specific reason in my opinion. I personally would rename it as well.
Anyway, from my point of view it is not a good approach to mix owning managed and unmanaged resources. As already mentioned in the comment even Microsoft recommends to encapsulate unmanaged resources into managed ones thus the cases where you need to implement finalizers are probably rare. I cannot remember when I did this myself the last time.
I am also not sticking to the implementation from the guidelines for multiple reasons, like misleading naming or because it's hard to understand. An alternative approach would be this answer.

Why .NET Object has method Finalize()?

I know that Finalize method is used by garbage collector to let object free up unmanaged resources. And from what I know, Object.Finalize is never called directly by GC (object is added to f-reachable queue during it's construction if it's type overrides the Finalize method by implementing finalizer).
Object.Finalize is only called from autogenerated finalizer code:
try
{
//My class finalize implementation
}
finally
{
base.Finalize(); // Here chain of base calls will eventually reach Object.Finalize/
}
So having an arbitrary class, derived from Object, wouldn't call Object.Finalize - you need finalizer for Object.Finalize to make sense and for most classes it doesn't make sense and is unused (not saying it's implementation is empty in fact).
Would it be too complex to check existence of Finalize method in a class without it overriding Object.Finalize, and generating root finalizer without try{}finally{base.Finalize()} call? Something similar to Add method for collection initializing - you don't have to implement any interface or override that method - just implement public void Add(item) method.
It would complicate C# compiler a bit, but make finalizer run slightly faster by removing one redundant call, and most importantly - make Object class easier to understand without having protected Finalize method with empty implementation while it doesn't need to finalize anything.
Also it might be possible to implement FinalizableObject class, derived from Object and make compiler derive all classes which have finalizer from that. It could implement IDisposable and make the disposing pattern, recommended by Microsoft reusable without need to implement it in every class. Actually I'm surprised such base class doesn't exist.
Edit
The garbage collection does not call the child implementation of Object.Finalise unless the method is overridden. Why is it available to all objects? So that it can be overridden when needed but unless it is there is no performance impact. Looking at documentation here, it states;
The Object class provides no implementation for the Finalize method, and the garbage collector does not mark types derived from Object for finalization unless they override the Finalize method.
Notes on finalization
Quoting directly from Ben Watson's excellent book Writing High-Performance .NET Code as he explains far better than I ever could;
Never implement a finalizer unless it is required. Finalizers are code, triggered by the garbage collector to cleanup unmanaged resources. They are called from a single thread, one after the other, and only after the garbage collector declares the object dead after a collection. This means that if your class implements a finalizer, you are guaranteeing that it will stay in memory even after the collection that should have killed it. This decreases overall GC efficiency and ensures that your program will dedicate CPU resources to cleaning up your object.
If you do implement a finalizer, you must also implement the IDisposable
interface to enable explicit cleanup, and call GC.SuppressFinalize(this)
in the Dispose method to remove the object from the finalization queue.
As long as you call Dispose before the next collection, then it will clean up the object properly without the need for the finalizer to run. The following example correctly demonstrates this pattern;
class Foo : IDisposable
{
~Foo()
{
Dispose(false);
}
public void Dispose()
{
Dispose(true);
GC.SuppressFinalize(this);
}
protected virtual void Dispose(bool disposing)
{
if (disposing)
{
this.managedResource.Dispose();
}
// Cleanup unmanaged resource
UnsafeClose(this.handle);
// If the base class is IDisposable object, make sure you call:
// base.Dispose();
}
}
Note Some people think that finalizers are guaranteed to run. This is generally true, but not absolutely so. If a program is force-terminated
then no more code runs and the process dies immediately. There is also a time limit to how long all of the finalizers are given on process shutdown. If your finalizer is at the end of the list, it may be skipped. Moreover,
because finalizers execute sequentially, if another finalizer has an infinite loop bug in it, then no finalizers after it will ever run. While finalizers are not run on a GC thread, they are triggered by a GC so if you have no collections, the finalizers will not run. Therefore, you should not rely on finalizers to clean up state external to your process.
Microsoft has a good write up on finalizers and the Disposable pattern here
The C# language destructor syntax obscures too much about what a finalizer really does. Perhaps best demonstrated with a sample program:
using System;
class Program {
static void Main(string[] args) {
var obj = new Example();
obj = null; // Avoid debugger extending its lifetime
GC.Collect();
GC.WaitForPendingFinalizers();
Console.ReadLine();
}
}
class Base { ~Base() { Console.WriteLine("Base finalizer called"); } }
class Derived : Base { ~Derived() { Console.WriteLine("Derived finalizer called"); } }
class Example : Derived { }
Output:
Derived finalizer called
Base finalizer called
There are some noteworthy things about this behavior. The Example class itself does not have a finalizer, yet its base class finalizers are called anyway. That the Derived class finalizer is called before the Base class finalizer is not accidental. And note that the Derived class' finalizer has no call to base.Finalize(), even though the MSDN article for Object.Finalize() demands that it does, yet it is called anyway.
You may easily recognize this behavior, it is the way a virtual method behaves. One whose override calls the base method, like virtual method overrides commonly do. Which is otherwise exactly what it is inside the CLR, Finalize() is a plain virtual method like any other. The actual code generated by the C# compiler for the Derived class' destructor resembles this:
protected override Derived.Finalize() {
try {
Console.WriteLine("Derived finalizer called");
}
finally {
base.Finalize();
}
}
Not valid code, but the way it could be reverse-engineered from the MSIL. The C# syntax sugar ensures you can never forget to call the base finalizer and that it can't be aborted by a thread abort or AppDomain unload. The C# compiler does not otherwise help and auto-generate a finalizer for the Example class; the CLR does the necessary work of finding the finalizer of the most-derived class, traversing the method tables of the base classes until it finds one. And likewise helps in the class loader by setting a flag to indicate that Example has base classes with a finalizer so needs to be treated specially by the GC. The Base class finalizer calls Object.Finalize(), even though it doesn't do anything.
So key point is that Finalize() is actually a virtual method. It therefore needs a slot in the method table for Object so a derived class can override it. Whether it could have been done differently is pretty subjective. Certainly not easily and not without forcing every language implementation to special-case it.

DRY IDisposable Pattern

A lot of my classes repeat the below code to implement IDisposable. This seems to violate the DRY (Don't Repeat Yourself) principle. I could avoid some of the work by creating an AbstractDisposable base class, but that seems inappropriate / wouldn't work if I needed to extend other existing objects (assuming those objects weren't themselves disposable).
Another option would be to use a template/meta language where I could specify lists of managed and unmanaged resources for each class and have the generic Dispose Pattern auto generated when I build my project - but so far I've not played with meta languages / this seems extreme for such a common scenario.
public class SomeDisposableClass : IDisposable
{
IDisposable _something; //a managed resource (unique to this class / here for illustration)
/* ... loads of code unique to this class ... */
#region Dispose Pattern
private bool _disposed = false;
~SomeDisposableClass()
{
Dispose(false);
}
public void Dispose()
{
Dispose(true);
GC.SuppressFinalize(this);
}
protected virtual void Dispose(bool disposing)
{
// Check to see if Dispose has already been called.
if (!this._disposed)
{
if (disposing)
{
// Dispose managed resources.
if (this._something!=null) this._something.Dispose(); //(unique to this class / here for illustration)
}
// Clean up any unmanaged resources
this._disposed = true;
}
}
#endregion
}
Is there a good way to implement a suitable Dispose pattern without violating the DRY principle?
I try to avoid IDisposable as best as I can. The problem is that it spreads throughout your code base. If a class has a disposable member, that class needs to implement IDisposable, too, etc.
Furthermore, IDisposable has problems when we are talking about type hierarchies.
A common scenario is to stick IDisposable onto a base class or even an interface if you think the derived classes need to free resources. However, most of the times, that's only an assumption and it really depends on the actual implementation if resource cleanup is needed or not, making the interface a leaky abstraction.
It would be better to only implement the interface if the class really needs it.
But this comes with its own problems:
How is the consumer of a certain interface supposed to know that the concrete instance he got - for example as a constructor parameter - needs to be disposed? He would have to explicitly check for it. And he would basically have to do this for every single instance of every non-sealed type he gets handed.
These are just two examples that show that you are best off to design your classes in a way so that they don't require the implementation of IDisposable.
However, if you really need to implement this interface, you should follow the Disposable Design Pattern as described by this CodeProject article.
It basically divides your types into two levels:
Level 0: Classes of level 0 contain only unmanaged resources, no managed ones. These classes need most of the usual default IDisposable pattern, although you don't have to implement the part that handles managed resources.
Level 1: Classes of level 1 contain only managed resources, both of Level 0 and 1. These classes only need a simplified implementation of IDisposable because they don't contain unmanaged resources. The implementation basically just calls Dispose on each of its Level 0 and Level 1 members and on its base class.
i don't think you are violating the DRY principle here. Because although you are disposing in each class but you are essentially not doing the same thing.,

Why should Dispose() be non-virtual?

I'm new to C#, so apologies if this is an obvious question.
In the MSDN Dispose example, the Dispose method they define is non-virtual. Why is that? It seems odd to me - I'd expect that a child class of an IDisposable that had its own non-managed resources would just override Dispose and call base.Dispose() at the bottom of their own method.
Thanks!
Typical usage is that Dispose() is overloaded, with a public, non-virtual Dispose() method, and a virtual, protected Dispose(bool). The public Dispose() method calls Dispose(true), and subclasses can use this protected virtual method to free up their own resorces, and call base.Dispose(true) for parent classes.
If the class owning the public Dispose() method also implements a finalizer, then the finalizer calls Dispose(false), indicating that the protected Dispose(bool) method was called during garbage collection.
If there is a finalizer, then the public Dispose() method is also responsible for calling GC.SuppressFinalize() to make sure that the finalizer is no longer active, and will never be called. This allows the garbage collector to treat the class normally. Classes with active finalizers generally get collected only as a last resort, after gen0, gen1, and gen2 cleanup.
This is certainly not an obvious one. This pattern was especially choosen because it works well in the following scenario's:
Classes that don't have a finalizer.
Classes that do have a finalizer.
Classes that can be inheritted from.
While a virtual Dispose() method will work in the scenario where classes don't need finalization, it doesn't work well in the scenario were you do need finalization, because those types often need two types of clean-up. Namely: managed cleanup and unmanaged cleanup. For this reason the Dispose(bool) method was introduced in the pattern. It prevents duplication of cleanup code (this point is missing from the other answers), because the Dispose() method will normally cleanup both managed and unmanaged resources, while the finalizer can only cleanup unmanaged resources.
Although methods in an interface are not "virtual" in the usual sense, they can nevertheless still be implemented in classes that inherit them. This is apparently a convenience built into the C# language, allowing the creation of interface methods without requiring the virtual keyword, and implementing methods without requiring the override keyword.
Consequently, although the IDisposable interface contains a Dispose() method, it does not have the virtual keyword in front of it, nor do you have to use the override keyword in the inheriting class to implement it.
The usual Dispose pattern is to implement Dispose in your own class, and then call Dispose in the base class so that it can release the resources it owns, and so on.
A type's Dispose method should release
all the resources that it owns. It
should also release all resources
owned by its base types by calling its
parent type's Dispose method. The
parent type's Dispose method should
release all resources that it owns and
in turn call its parent type's Dispose
method, propagating this pattern
through the hierarchy of base types.
http://msdn.microsoft.com/en-us/library/fs2xkftw.aspx
The Dispose method should not be virtual because it's not an extension point for the pattern to implement disposable. That means that the base disposable class in a hierarchy will create the top-level policy (the algorithm) for dispose and will delegate the details to the other method (Dispose(bool)). This top-level policy is stable and should not be overridden by child classes. If you allow child classes to override it, they might not call all the necessary pieces of the algorithm, which might leave the object in an inconsistent state.
This is akin to the template method pattern, in which a high-level method implements an algorithm skeleton and delegates the details to other overridable methods.
As a side note, I prefer another high-level policy for this particular pattern (which still uses a non-virtual Dispose).
Calls through an interface are always virtual, regardless of whether a "normal" call would be direct or virtual. If the method that actually does the work of disposing isn't virtual except when called via the interface, then any time the class wants to dispose itself it will have to make sure to cast its self-reference to iDisposable and call that.
In the template code, the non-virtual Dispose function is expected to always be the same in the parent and the child [simply calling Dispose(True)], so there's never any need to override it. All the work is done in the virtual Dispose(Boolean).
Frankly, I think using the Dispose pattern is a little bit silly in cases where there's no reason to expect descendant classes to directly hold unmanaged resources. In the early days of .net it was often necessary for classes to directly hold unmanaged resources, but today in most situations I see zero loss from simply implementing Dispose() directly. If a future descendant class needs to use unmanaged resources, it can and typically should wrap those resources in their own Finalizable objects.
On the other hand, for certain kinds of method there can be advantages to having a non-virtual base class method whose job is to chain to a protected virtual method, and having the virtual method be called Dispose(bool) is really no worse than VirtDispose() even if the supplied argument is rather useless. In some situations, for example, it may be necessary for all operations on an object to be guarded by a lock which is owned by the base-class object. Having the non-virtual base-class Dispose acquire the lock before calling the virtual method will free all the base classes from having to worry about the lock themselves.
The reason the sample's Dispose() method is non-virtual is because they take over the entire process in that example, and leave subclasses with the virtual Dispose(bool disposing) method to override. You'll notice that in the example, it stores a boolean field to ensure that the Dispose logic does not get invoked twice (potentially once from IDisposable, and once from the destructor). Subclasses who override the provided virtual method do not have to worry about this nuance. This is why the main Dispose method in the example is non-virtual.
I've got a quite detailed explanation of the dispose pattern here. Essentially, you provide a protected method to override that is more robust for unmanaged resources instead.
If the base class has resources that need to be cleaned up at Dispose() time, then having a virtual Dispose method that's overridden by an inheriting class prevents those resources from being released unless the inheriting class specifically calls the
base's Dispose method. A better way would implement it would be to have each derived class implement IDisposable.
Another, not so obvious reason is to avoid the need to suppress CA1816 warnings for derived classes. These warnings look like this
[CA1816] Change Dispose() to call GC.SuppressFinalize(object). This will prevent derived types that introduce a finalizer from needing to re-implement 'IDisposable' to call it.
Here is an example
class Base : IDisposable
{
public virtual void Dispose()
{
...
GC.SuppressFinalize(this);
}
}
public class Derived : Base
{
public override void Dispose() // <- still warns for CA1816
{
base.Dispose();
...
}
}
You can resolve this by just adopting the recommended Dispose pattern.

Using IDisposable to unsubscribe an event-- do I need to put other things inside the dispose?

I have the following class
public class Presenter: IDisposable
{
public IView View
{get;private set;}
//snip other object reference, all managed
public Presenter(IView view)
{
View=view;
View.MouseUp += MouseUpEvent;
}
public void MouseUpEvent()
{
//do whatever you want to do on mouse up
}
public void Dispose()
{
View.MouseUp -= MouseUpEvent;
// no more manual disposing
}
}
The question now is, am I implement Dispose() method correctly? Or do I need to manually dispose all the other managed objects just because I have explicilty define Dispose()?
I reckon that the GC is smart enough to do its own disposing ( except the event subscription) even without me manually doing it. Am I right?
If you go with the choice of subscribing in the constructor, then this looks reasonable. I would echo Josh's sentiments that it may not be the best approach. On the other hand, it may be the simplest way of achieving your goal, which is always a good thing. I'm not going to pretend to be an expert on UI patterns: having raised the concern, I'll assume that this is the way you want to work, and address the question itself :)
I personally find Josh's prescribed pattern1 overly complex for simple scenarios - your approach is fine, with just one change: make your class sealed. If you don't want to seal the class, you should go for the Dispose(bool) option (but without the finalizer) because subclasses may also need to dispose of things, and may need a finalizer. Without the possibility of a derived type, life is simpler (as it so often is).
You don't need to do anything with other members just because you now implement IDiposable for that one reason.
So, do you need to derive any further from this class?
1 I do understand that this is the standard recommended pattern, although I'd recommend that you read the advice of Joe Duffy et al for even more details - it can all get very complicated.
Personally, I would avoid hooking/unhooking the event in the constructor and dispose. Instead I would add code to the View get/set accessors and add them there. But if the Presenter is disposed while a View is attached, I would not bother trying to clean that up. You can explicitly detach the View from the presenter if you need explicit detaching.
Having said that, here's what I know about IDisposable.
The recommended approach to implementing IDisposable is to have a protected Dispose(bool) method where you take action. The reason is, you want to distinguish between an explicit disposal and a disposal caused by finalization (garbage collection.)
When you are being disposed because of an explicit Dispose() call, it's ok to touch managed objects and you are expected to dispose of anything you've created that also needs disposing. So you do this only when disposing=true.
But if someone (you) forgets to call Dispose and the finalizer is called, you're being disposed after garbage collection (disposing=false) and you don't want to touch any managed objects because they may already be finalized. The only thing you need to free up in this case is unmanaged resources like Win32 handles and such.
Finally, when Dispose() is explicitly called you'll notice I called GC.SupressFinalize(this) which is a performance hint for the garbage collector. It lets it know that the object doesn't need to be finalized when it is collected. Finalization isn't cheap.
class MyObject : IDisposable {
~MyObject() {
Dispose(false);
}
public void Dispose() {
Dispose(true);
GC.SupressFinalize(this);
}
protected virtual void Dispose(bool disposing) {
if (disposing) {
// dispose of managed resources
}
// dispose of unmanaged resources
}
}

Categories

Resources