still trying to understand the dispose pattern - c#

i've read msdn and various posts about dispose pattern, and there are still a couple of things i don't understand. I've written the following code to test the dispose pattern. Please note that there aren't unmanged resources, i'm using vs2008 and .net 3.5 :
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
private void tryDispose()
{
//test 1 : allocate resource and leave manage it to gc
BL.myclass df = new BL.myclass();
//test 2 : try to force garbage collecting
//GC.Collect();
//test 3 : call dispose myself
//using (BL.myclass df = new BL.myclass())
//{
//}
}
private void button1_Click(object sender, EventArgs e)
{
tryDispose();
}
this is my disposable class:
class myclass: IDisposable
{
private StronglyTypedDs myDS;
private bool _disposed;
public myclass()
{
using (myDSTableAdapter docDocadpt = new myDSTableAdapter())
{
myDS = new StronglyTypedDs();
docDocadpt.Fill(myDS.TheTable);
}
}
#region IDisposable Members
public void Dispose()
{
Dispose(true);
GC.SuppressFinalize(this);
}
~myclass()
{
Dispose(false);
}
protected virtual void Dispose(bool disposing)
{
if (!_disposed)
{
if (disposing)
{
if (myDS != null)
myDS .Dispose();
myDS = null;
}
}
_disposed = true;
}
#endregion
}
The results are :
test 1a - just instantiating myclass, the destructor is commentend since myclass doesn't contains unmanaged resources : myclass.dispose is not called, even if i close the application (whose dispose is executed instead) . So what's the state of the dataset once i close the application ?
test 1b - uncommenting destructor, it's ok all disposes are called when i close the application.
test 2a and 2b - i do the above test just calling gc.collect : the behaviour is identical to test 1a and 1b respectively
test 3 - everything works fine (of course)
many posts says that, if myclass doesn't contains unmanaged resources, i don't need to add the destructor; yet in my tests , if i don't add the destructor , myclass.dispose doesn't get called when i close the application. I haven't waited for the gc to run by itself (if i remember correctly gc.collect doesn't guarantes the class instance is deallocated) to check if it will call myclass.dispose .
So what's the correct implemention : always define e destructor or avoid it if myclass contains only managed resources ?
If i had filled all generations levels, would had the gc called myclass dispose or not without having implemented a destructor?
Finally i've noticed that if i define a destructor , but don't declare the class as implementing IDisposable, the disposing chain works anyway. This could make sense since the destructor might be translated to finalize in IL. But i find it really confusing : is it some kind of "implicit" interface implementation i don't know? gc can dispose the item but users can't
thank you in advance
Stefano

Trust your Garbage Collector. Managed resources will get cleaned up, eventually. There is no need for a finalizer or implementing IDisposable unless you have some external resource that needs to be released.
This typically means that you only should implement IDisposable when you either:
Are wrapping a native resource. (In this case, you probably also want a finalizer.)
Are encapsulating a class which implements IDisposable. (In this case, you want IDisposable, but don't need to implement a finalizer/destructor.)
Part of the confusion with IDisposable, in my opinion, is that it covers quite a few use cases, and the proper implementation changes depending on what you're doing (ie: wrapping native resources, wrapping other IDisposable classes, or using Factored types). To address this, I've written a multiple part series on IDisposable - it might help clarify some of this for you.

The correct pattern is to only use a finalizer when your class contains unmanaged resources. As to relying on the GC to dispose of your managed objects, don't. The IDisposable contract makes it clear that this object needs to be disposed.

Ok i think i've understood, referring to my example its correct to implement a dispose because the dataset is global to my class and implements IDisposable , while i don't need the finalizer because there aren't unmanaged resources.
Even if i "forget" to dispose some managed resource in my class dispose method, the gc will collect it at some point. The dispose method is just an utility i provide to other classes/developers for managed resources, a must with the finalizer if i wrap unmanaged resources .
i'll read the articles you have provided asap, but in the mean time i've the last question : when gc will free memory owned by my class and its resources ? when someone calls dispose or when it will run (it will free memory instead of moving it to next generation ) ?
thank you everybody for your answers and examples

I wrote a brief seris entitled How to Implement IDisposable and Finalizers: 3 Easy Rules. It describes a much simpler approach that Microsoft themselves have followed since the 2.0 version of the BCL.
The "official" pattern is needlessly complex and needlessly confusing.

Your code is correct, you've implemented it exactly like it is documented in the MSDN library.
You'll need to take a second look though. Reason what happens when the destructor (aka finalizer) runs. The disposing argument will be false, the protected Dispose method does nothing. This is entirely normal, finalizers should only ever release unmanaged resources. You don't have any. It is extraordinary rare to ever have an unmanaged resource in your own code. They belong in the nice wrapper classes available in .NET to turn an unmanaged operating resource into a nice managed class. If you find yourself thinking you need a finalizer, you'll be wrong 99.99% of the time. Even if you do wrap an unmanaged resource, you should use one of the SafeHandle wrappers. And rely on their finalizers.
Okay, you want to get rid of the destructor. It isn't healthy to leave it in, it keeps the object in memory longer than necessary. When you do, you'll cut it down to:
public void Dispose()
{
if (myDS != null) myDS.Dispose();
}
Which is the boiler-plate implementation of most any Dispose() method, just call the Dispose method of members of the class. You can completely omit it if you don't have any members with a Dispose() method.
Next, you do misunderstand how the Dispose() method gets called. It is not automatic. Which is the point of having it in the first place, releasing resources automatically is already taken care of by the garbage collector. The Dispose() method is there for you to call, either with the using statement or calling it directly. So that you can release the resource early instead of waiting for the garbage collector finalizer thread to get around to it. Which can take a while. Call it when you know that your program won't be using the object anymore.
If your DataSet is actively used by the form then you cannot dispose it until the form closes. Call the class' Dispose() method in a FormClosed event handler. Or, better, open the form's Designer.cs file, cut-and-paste the Dispose() method you find in there and move it to the form's source code file. And add the dispose call. I know that's a bit confuzzling, but the only time it's okay to edit the designer file.

The main purpose of IDisposable is to have a consistent standard interface you can dispose of unmanaged resources with, that is if you didn't do something to ensure Dispose() was called these resources would hang around after the app was closed. Also understood by the using() syntax, that is using will implement the following block for you:
DisposableType someDisposable = new DisposableType();
try
{
// Do whatever
}
finally
{
((IDisposable)someDisposable).Dispose();
}
This is all implemented in a nice design like so:
using(DisposableType someDisposable = new DisposableType())
{
// Do whatever
}

Related

Destructor in C# basic program does not work (output missing)

I have written the very basic program below, I am new to C#. The destructor ~Program() doesn't get called, so I do not see in the output the 'Destructor called' string. I have checked other similar questions but I don't find the answer to mine. Thanks.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using static System.Console;
namespace LyfeCicleObject
{
class Program
{
public Program()
{
WriteLine("Cons called");
}
~Program()
{
WriteLine("Destructor called");
}
static void Main(string[] args)
{
WriteLine("Main started");
Program p1 = new Program();
{
WriteLine("Block started");
Program p2 = new Program();
WriteLine("Block ended");
}
WriteLine("Main ended");
}
}
}
The short answer -- the reason you're not seeing the "Destructor called" output -- was buried somewhere in the comments:
.NET Core does not run finalizers at the end of the program
(See: Finalizers (C# Programming Guide)).
.NET Framework will attempt to do it but .NET Core just won't do it.
Disclaimer: We have no way of knowing if these statements will continue to hold true; this is how they're implemented and documented as of now.
According to Raymond Chen, though, in his post Everybody thinks about garbage collection the wrong way, it would not be invalid if .NET Framework didn't run finalizers at the end of the program, either. The relevant quote, which says it from a different perspective, is this:
A correctly-written program cannot assume that finalizers will ever run.
So as long as you don't assume that finalizers will run, it shouldn't matter how they're implemented or if an implementation changes.
Before going any further with C#, you're going to have to abandon the idea of destructors in .NET because they simply don't exist. C# uses C++'s destructor syntax for finalizers but the similarities stop there.
The good news is that there is a way to do something close to what you were trying to do, but it takes a paradigm shift, a substantial change in how you think about resource acquisition and release. Whether or not you really need to do it is a totally different question.
Finalizers aren't the only way, or even the best way, to release resources that need to be released in a timely manner. We have the disposable pattern to help with that.
The disposable pattern allows class implementors to opt in to a common mechanism for deterministically releasing resources (not including memory on the managed heap). It includes finalizers but only as a last chance at cleanup if the object wasn't disposed properly, especially if the process isn't terminating.
I'd say the main differences you'll see compared to C++ destructors are:
There's more that the class's implementor must do support the disposable pattern.
The class's consumer also has to opt in to it with a using statement.
What you won't see is that the memory won't necessarily be reclaimed immediately.
If you want to know more about how, read on...
Before I get into any code, it's worth mentioning some points of caution:
A finalizer should never be empty. It causes instances to be kept alive longer and for nothing.
As mjwills stated in a comment, 99.9% of the time, you shouldn't be writing a finalizer. If you find yourself writing one, take a step back and make sure you have a good reason to do it in terms of .NET code and not because you would do it that way in C++.
More often than not, you'll be overriding Dispose(bool) after deriving from a class that implements the disposable pattern rather than creating the base of a class hierarchy that needs to be disposable. For example, the .Designer.cs files in Windows Forms applications override Dispose(bool) in order to dispose of the components field if it's not null.
Okay, code...
The following is an example of a simple class that implements the disposable pattern. It doesn't provide support for child classes so it's marked sealed and Dispose(bool) is private.
public sealed class SimpleDisposable : IDisposable
{
public SimpleDisposable()
{
// acquire resources
}
~SimpleDisposable()
{
Dispose(false);
}
public void Dispose()
{
// Suppress calling the finalizer because resources will have been released by then.
GC.SuppressFinalize(this);
Dispose(true);
}
private void Dispose(bool disposing)
{
if (disposing)
{
// release managed resources
// (you don't want to do this when calling from the finalizer because the GC may have already finalized and collected them)
}
// release unmanaged resources
}
}
Actual cleanup takes place in the Dispose(bool) method. If the parameter is true, it means that disposal is happening via the IDisposable interface (usually a using statement but not necessarily) and it's okay to clean up managed resources as well. If it's false, it means that disposal is happening as part of a GC sweep, so you can't touch managed resources because they may have already been collected.
If you're writing a base class that needs to support the disposable pattern, things change slightly: Dispose(bool) is becomes protected and virtual so it can be overridden by subclasses but is still inaccessible to the consumer.
The following is an example of a base class that supports the disposable pattern for subclasses.
public abstract class BaseDisposable : IDisposable
{
protected BaseDisposable()
{
// acquire resources
}
~BaseDisposable()
{
Dispose(false);
}
public void Dispose()
{
GC.SuppressFinalize(this);
Dispose(true);
}
protected virtual void Dispose(bool disposing)
{
if (disposing)
{
// release managed resources
}
// release unmanaged resoures
}
}
And then the following is a subclass that uses that support. Subclasses don't also need to implement the finalizer or IDisposable.Dispose. All they have to do is override Dispose(bool), dispose of their own resources, and then call the base implementation.
public class DerivedDisposable : BaseDisposable
{
public DerivedDisposable()
{
// acquire resources for DerivedDisposable
}
protected override void Dispose(bool disposing)
{
if (disposing)
{
// release DerivedDisposable's managed resources
}
// release DerivedDisposable's unmanaged resources
// Let the base class do its thing
base.Dispose(disposing);
}
}
So what does it mean to dispose managed and unmanaged resources?
Managed resources are things like other disposable objects and even non-disposable objects (e.g. strings). Some disposable types in the BCL will set such fields to null to ensure that the GC doesn't find active references to them.
When your class is being disposed, the consumer has decided that it and its resources are no longer needed. If your object contains other disposables, it's okay to dispose those objects, and so on down the chain, because it's not happening during garbage collection.
Unmanaged resources are things like file handles, global memory, kernel objects... pretty much anything you allocated by making a call to the operating system. Those aren't affected by the garbage collector and need to be released no matter what, so they're not subject to the disposing test.
If your disposable object used another disposable object that has an unmanaged resource, it's that object's responsibility to implement the Disposable pattern to release its resources, and your responsibility to use it.
Not all objects that implement IDisposable actually have unmanaged resources. Often a base class will support the disposable pattern simply because its author knows that at least one class that derives from it might need to use unmanaged resources. However, if a class doesn't implement the disposable pattern, one of its subclasses can introduce that support if it needs it.
Let's alter your program a bit and make it do what you were expecting, but using the disposable pattern now.
Note: As far as I know, it's not very common to have Main create an instance of the containing Program class. I'm doing it here to keep things as close to the original as possible.
using System;
internal sealed class Program : IDisposable
{
private readonly string _instanceName;
public Program(string instanceName)
{
_instanceName = instanceName;
Console.WriteLine($"Initializing the '{_instanceName}' instance");
}
~Program()
{
Dispose(false);
}
public void Dispose()
{
GC.SuppressFinalize(this);
Dispose(true);
}
private void Dispose(bool disposing)
{
if (disposing)
{
Console.WriteLine($"Releasing the '{_instanceName}' instance's managed resources");
}
Console.WriteLine($"Releasing the '{_instanceName}' instance's unmanaged resources");
}
private static void Main(string[] args)
{
Console.WriteLine("Main started");
Program p0 = new Program(nameof(p0));
using (Program p1 = new Program(nameof(p1)))
{
Console.WriteLine("Outer using block started");
using (Program p2 = new Program(nameof(p2)))
{
Console.WriteLine("Inner using block started");
Console.WriteLine("Inner using block ended");
}
Console.WriteLine("Outer using block ended");
}
Console.WriteLine("Main ended");
}
}
Build and run against .NET Framework 4.7.2 and you get the following output:
Main started
Initializing the 'p0' instance
Initializing the 'p1' instance
Outer using block started
Initializing the 'p2' instance
Inner using block started
Inner using block ended
Releasing the 'p2' instance's managed resources
Releasing the 'p2' instance's unmanaged resources
Outer using block ended
Releasing the 'p1' instance's managed resources
Releasing the 'p1' instance's unmanaged resources
Main ended
Releasing the 'p0' instance's unmanaged resources
Build and run against .NET Core 2.1 and you get the following output:
Main started
Initializing the 'p0' instance
Initializing the 'p1' instance
Outer using block started
Initializing the 'p2' instance
Inner using block started
Inner using block ended
Releasing the 'p2' instance's managed resources
Releasing the 'p2' instance's unmanaged resources
Outer using block ended
Releasing the 'p1' instance's managed resources
Releasing the 'p1' instance's unmanaged resources
Main ended
Instances p1 and p2 were disposed in the reverse order in which they were constructed because of the using statements, and both managed and unmanaged resources were released. This was the desired behavior behind trying to use a "destructor".
On the other hand, .NET Framework and .NET Core did things a bit different at the end, showing the differences I mentioned at the beginning:
.NET Framework's GC called the finalizer for p0 so it only released the unmanaged resources.
.NET Core's GC did not call the finalizer for p0.
If you want to see the output from finalizer:
add new method
initialize variable p1 inside
add GC.Collect()
call new method from Main
profit
If you want to know the reason of current behavior: the p1 variable exists in the scope of the Main method and will be collected by the GC when scope gets unreachable and I suppose it happens when program already stopped that means no GC (memory will be released in another way).

Why using Dispose as a normal method is bad?

Trying to figure it out. Someone told me
Dispose is not just a method - it's equivalent to a destructor in other languages.
Ok. Msdn is also very loud about this.
But then
class Test : IDisposable
{
public string Property { get; set; } = "Test";
public void Dispose() => Console.WriteLine("Disposed, very scary");
}
class Program
{
static void Main(string[] args)
{
var test = new Test();
test.Dispose();
test.Property = "123"; // but it's disposed OMG! do not do this!
test.Dispose();
using (var another = new Test())
for (int i = 0; i < 10; i++)
{
another.Dispose();
GC.Collect(); // or what should I call to make it crash?
}
Console.ReadKey();
}
}
And there are no problems.
What I think about Dispose:
it's a normal public method;
IDisposable is useful in conjunction with using to automatically call Dispose, nothing more;
it's totally fine to put into dispose any code an call it internally at any time if object state properly maintained.
Correct me if I am wrong.
P.S: Downvote means "question is bad/not useful/has problem". If you simply disagree with my thoughts - post comment or answer. It will be useful for people who think as I do right now (because I am wrong? then prove it)
Dispose is just a method, you can call it just like any other method. It is always exposed through the IDisposable interface (yes, obviously you can name a method Dispose without implementing IDisposable, don't do that!).
However, calling it manually is sometimes a code smell, smell of code that should probably be using using instead. By "manually" here I mean calling Dispose outside of the implementation of another Dispose.
Calling it twice should also be safe and is documented:
If an object's Dispose method is called more than once, the object must ignore all calls after the first one. The object must not throw an exception if its Dispose method is called multiple times. Instance methods other than Dispose can throw an ObjectDisposedException when resources are already disposed.
(my emphasis)
Should you be calling Dispose twice? No!. That is also a code smell of code that no longer has control of what it has done and what it has left to do and ends up doing things "just to be sure". Don't do that either!
So if you write code correctly, sure you can call Dispose manually.
You're right, Dispose is just another method, belonging to IDisposable. It just has the added benefit of being able to be automatically called when a using() scope ends - it is not equivalent to a destructor and whoever told you that doesn't truly understand what they're saying.
I'd always use a using() block where possible, but if you're careful you can manually call Dispose instead and it will have the same effect.
Visual Studio 2015 offers up (finally) a suggested pattern for implementation of IDisposable which matches the guidelines.
This is the stub that VS creates for you when selecting to implement the disposable pattern. The TODOs guide us through the implementation.
class Disposable : IDisposable
{
#region IDisposable Support
private bool disposedValue = false; // To detect redundant calls
protected virtual void Dispose(bool disposing)
{
if (!disposedValue)
{
if (disposing)
{
// TODO: dispose managed state (managed objects).
}
// TODO: free unmanaged resources (unmanaged objects) and override a finalizer below.
// TODO: set large fields to null.
disposedValue = true;
}
}
// TODO: override a finalizer only if Dispose(bool disposing) above has code to free unmanaged resources.
// ~Disposable() {
// // Do not change this code. Put cleanup code in Dispose(bool disposing) above.
// Dispose(false);
// }
// This code added to correctly implement the disposable pattern.
public void Dispose()
{
// Do not change this code. Put cleanup code in Dispose(bool disposing) above.
Dispose(true);
// TODO: uncomment the following line if the finalizer is overridden above.
// GC.SuppressFinalize(this);
}
#endregion
}
Note the use of a flag to indicate if the Dispose has already been called. This flag can be used to throw ObjectDisposedException instances on method calls and properties across the classes implementation.
The intention of Dispose has always been to clean up unmanaged resources. However, the syntactic sugar of the using keyword (requires an IDisposable) lets you create really tidy 'context' pattern classes for managing resource access, even if there are no unmanaged resources used.
As usual, document the usage and the intentions clearly and you can't go wrong but please avoid methods called 'Dispose' if you don't implement the interface.
There is a critical difference between Dispose in .NET versus destructors in other languages: if one has a pointer to an object in another language and the object is deleted, one will have an invalid pointer and there is no way to do anything with it, including determine whether it is still valid, without invoking Undefined Behavior. By contrast, in .NET if one has a reference to an object which gets Disposed, the reference will continue to be a valid reference to the object in question. The object will likely refuse to do much because it's been disposed, but such refusal is affirmatively generated by the object itself. No Undefined Behavior involved.
On the flip side, when a destructor is invoked in other languages like C++ an object can be certain that no valid pointers exist to it anymore, but that is not true of Dispose. Consequently, code should avoid pooling public-facing objects and instead have every request for a new object return a new object (which may be a wrapper to a pooled object). If no reference to the pooled object exists outside the wrapper, and Dispose invalidates that reference before returning the object to the pool, then a future object request can be satisfied by encapsulating the pooled object in a new wrapper which will again hold the only reference to it.

Why should we call SuppressFinalize when we don't have a destructor

I have few Question for which I am not able to get a proper answer .
1) Why should we call SuppressFinalize in the Dispose function when we don't have a destructor .
2) Dispose and finalize are used for freeing resources before the object is garbage collected. Whether it is managed or unmanaged resource we need to free it , then why we need a condition inside the dispose function , saying pass 'true' when we call this overridden function from IDisposable:Dispose and pass false when called from a finalize.
See the below code I copied from net.
class Test : IDisposable
{
private bool isDisposed = false;
~Test()
{
Dispose(false);
}
protected void Dispose(bool disposing)
{
if (disposing)
{
// Code to dispose the managed resources of the class
}
// Code to dispose the un-managed resources of the class
isDisposed = true;
}
public void Dispose()
{
Dispose(true);
GC.SuppressFinalize(this);
}
}
what if I remove the boolean protected Dispose function and implement the as below.
class Test : IDisposable
{
private bool isDisposed = false;
~Test()
{
Dispose();
}
public void Dispose()
{
// Code to dispose the managed resources of the class
// Code to dispose the un-managed resources of the class
isDisposed = true;
// Call this since we have a destructor . what if , if we don't have one
GC.SuppressFinalize(this);
}
}
I'm going out on a limb here, but... most people don't need the full-blown dispose pattern. It's designed to be solid in the face of having direct access to unmanaged resources (usually via IntPtr) and in the face of inheritance. Most of the time, neither of these is actually required.
If you're just holding a reference to something else which implements IDisposable, you almost certainly don't need a finalizer - whatever holds the resource directly is responsible for dealing with that. You can make do with something like this:
public sealed class Foo : IDisposable
{
private bool disposed;
private FileStream stream;
// Other code
public void Dispose()
{
if (disposed)
{
return;
}
stream.Dispose();
disposed = true;
}
}
Note that this isn't thread-safe, but that probably won't be a problem.
By not having to worry about the possibility of subclasses holding resources directly, you don't need to suppress the finalizer (because there isn't one) - and you don't need to provide a way of subclasses customising the disposal either. Life is simpler without inheritance.
If you do need to allow uncontrolled inheritance (i.e. you're not willing to bet that subclasses will have very particular needs) then you need to go for the full pattern.
Note that with SafeHandle from .NET 2.0, it's even rarer that you need your own finalizer than it was in .NET 1.1.
To address your point about why there's a disposing flag in the first place: if you're running within a finalizer, other objects you refer to may already have been finalized. You should let them clean up themselves, and you should only clean up the resources you directly own.
Here are the main facts
1) Object.Finalize is what your class overrides when it has a Finalizer. the ~TypeName() destructor method is just shorthand for 'override Finalize()' etc
2) You call GC.SuppressFinalize if you are disposing of resources in your Dispose method before finalization (i.e. when coming out of a using block etc). If you do not have a Finalizer, then you do not need to do this. If you have a Finalizer, this ensures that the object is taken off of the Finalization queue (so we dont dispose of stuff twice as the Finalizer usually calls the Dispose method as well)
3) You implement a Finalizer as a 'fail safe' mechanism. Finalizers are guaranteed to run (as long as the CLR isnt aborted), so they allow you to make sure code gets cleaned up in the event that the Dispose method was not called (maybe the programmer forgot to create the instance within a 'using' block etc.
4) Finalizers are expensive as Types that have finalizers cant be garbage collected in a Generation-0 collection (the most efficient), and are promoted to Generation-1 with a reference to them on the F-Reachable queue, so that they represent a GC root. it's not until the GC performs a Generation-1 collection that the finalizer gets called, and the resources are released - so implement finalizers only when very important - and make sure that objects that require Finalization are as small as possible - because all objects that can be reached by your finalizable object will be promoted to Generation-1 also.
Keep the first version, it is safer and is the correct implementation of the dispose pattern.
Calling SuppressFinalize tells the GC that you have done all the destruction/disposing yourself (of resources held by your class) and that it does not need to call the destructor.
You need the test in case the code using your class has already called dispose and you shouldn't tell the GC to dispose again.
See this MSDN document (Dispose methods should call SuppressFinalize).
1. Answer for the first question
Basically, you don't have to call SuppressFinalize method if your class doesn't have a finalize method (Destructor). I believe people call SupressFinalize even when there is no finalize method because of lack of knowledge.
2. Answer for the second question
Purpose of the Finalize method is to free un-managed resources. The most important thing to understand is that, Finalize method is called when the object is in the finalization queue. Garbage collector collects all the objects that can be destroy. Garbage Collector adds objects those have got finalization to the finalization queue before destroy. There is another .net background process to call the finalize method for the objects those are in the finalization queue. By the time that background process execute the finalize method, that particular object's other managed reference may have been destroyed. Because there is no specific order when it comes to the finalization execution. So, the Dispose Pattern wants to make sure that finalize method do not try to access managed objects. That's why managed objects are going in side "if (disposing)" clause which is unreachable for the finalize method.
You should always call SuppressFinalize() because you might have (or have in the future) a derived class that implements a Finalizer - in which case you need it.
Let's say you have a base class that doesn't have a Finalizer - and you decided not to call SuppressFinalize(). Then 3 months later you add a derived class that adds a Finalizer. It is likely that you will forget to go up to the base class and add a call to SuppressFinalize(). There is no harm in calling it if there is no finalizer.
My suggested IDisposable pattern is posted here: How to properly implement the 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
}
}

Finalize vs Dispose

Why do some people use the Finalize method over the Dispose method?
In what situations would you use the Finalize method over the Dispose method and vice versa?
The finalizer method is called when your object is garbage collected and you have no guarantee when this will happen (you can force it, but it will hurt performance).
The Dispose method on the other hand is meant to be called by the code that created your class so that you can clean up and release any resources you have acquired (unmanaged data, database connections, file handles, etc) the moment the code is done with your object.
The standard practice is to implement IDisposable and Dispose so that you can use your object in a using statment. Such as using(var foo = new MyObject()) { }. And in your finalizer, you call Dispose, just in case the calling code forgot to dispose of you.
Others have already covered the difference between Dispose and Finalize (btw the Finalize method is still called a destructor in the language specification), so I'll just add a little about the scenarios where the Finalize method comes in handy.
Some types encapsulate disposable resources in a manner where it is easy to use and dispose of them in a single action. The general usage is often like this: open, read or write, close (Dispose). It fits very well with the using construct.
Others are a bit more difficult. WaitEventHandles for instances are not used like this as they are used to signal from one thread to another. The question then becomes who should call Dispose on these? As a safeguard types like these implement a Finalize method, which makes sure resources are disposed when the instance is no longer referenced by the application.
Finalize is the backstop method, called by the garbage collector when it reclaims an object. Dispose is the "deterministic cleanup" method, called by applications to release valuable native resources (window handles, database connections, etc.) when they are no longer needed, rather than leaving them held indefinitely until the GC gets round to the object.
As the user of an object, you always use Dispose. Finalize is for the GC.
As the implementer of a class, if you hold managed resources that ought to be disposed, you implement Dispose. If you hold native resources, you implement both Dispose and Finalize, and both call a common method that releases the native resources. These idioms are typically combined through a private Dispose(bool disposing) method, which Dispose calls with true, and Finalize calls with false. This method always frees native resources, then checks the disposing parameter, and if it is true it disposes managed resources and calls GC.SuppressFinalize.
Finalize gets called by the GC when this object is no longer in use.
Dispose is just a normal method which the user of this class can call to release any resources.
If user forgot to call Dispose and if the class have Finalize implemented then GC will make sure it gets called.
Finalize
Finalizers should always be protected, not public or private so that the method cannot be called from the application's code directly and at the same time, it can make a call to the base.Finalize method
Finalizers should release unmanaged resources only.
The framework does not guarantee that a finalizer will execute at all on any given instance.
Never allocate memory in finalizers or call virtual methods from finalizers.
Avoid synchronization and raising unhandled exceptions in the finalizers.
The execution order of finalizers is non-deterministic—in other words, you can't rely on another object still being available within your finalizer.
Do not define finalizers on value types.
Don't create empty destructors. In other words, you should never explicitly define a destructor unless your class needs to clean up unmanaged resources and if you do define one, it should do some work. If, later, you no longer need to clean up unmanaged resources in the destructor, remove it altogether.
Dispose
Implement IDisposable on every type that has a finalizer
Ensure that an object is made unusable after making a call to the Dispose method. In other words, avoid using an object after the Dispose method has been called on it.
Call Dispose on all IDisposable types once you are done with them
Allow Dispose to be called multiple times without raising errors.
Suppress later calls to the finalizer from within the Dispose method using the GC.SuppressFinalize method
Avoid creating disposable value types
Avoid throwing exceptions from within Dispose methods
Dispose/Finalized Pattern
Microsoft recommends that you implement both Dispose and Finalize when working with unmanaged resources. The Finalize implementation would run and the resources would still be released when the object is garbage collected even if a developer neglected to call the Dispose method explicitly.
Cleanup the unmanaged resources in the Finalize method as well as Dispose method. Additionally call the Dispose method for any .NET objects that you have as components inside that class(having unmanaged resources as their member) from the Dispose method.
There're some keys about from the book MCSD Certification Toolkit (exam 70-483) pag 193:
destructor ≈(it's almost equal to) base.Finalize(), The destructor is converted into an override version of the Finalize method that executes the destructor’s code and then calls the base class’s Finalize method. Then its totally non deterministic you can't able to know when will be called because depends on GC.
If a class contains no managed resources and no unmanaged resources, it shouldn't implement IDisposable or have a destructor.
If the class has only managed resources, it should implement IDisposable but it shouldn't have a destructor. (When the destructor executes, you can’t be sure managed objects still
exist, so you can’t call their Dispose() methods anyway.)
If the class has only unmanaged resources, it needs to implement IDisposable and needs a destructor in case the program doesn’t call Dispose().
Dispose() method must be safe to run more than once. You can achieve that by using a variable to keep track of whether it has been run before.
Dispose() should free both managed and unmanaged resources.
The destructor should free only unmanaged resources. When the destructor executes, you
can’t be sure managed objects still exist, so you can’t call their Dispose methods anyway. This is obtained by using the canonical protected void Dispose(bool disposing) pattern, where only managed resources are freed (disposed) when disposing == true.
After freeing resources, Dispose() should call GC.SuppressFinalize, so the object can
skip the finalization queue.
An Example of a an implementation for a class with unmanaged and managed resources:
using System;
class DisposableClass : IDisposable
{
// A name to keep track of the object.
public string Name = "";
// Free managed and unmanaged resources.
public void Dispose()
{
FreeResources(true);
// We don't need the destructor because
// our resources are already freed.
GC.SuppressFinalize(this);
}
// Destructor to clean up unmanaged resources
// but not managed resources.
~DisposableClass()
{
FreeResources(false);
}
// Keep track if whether resources are already freed.
private bool ResourcesAreFreed = false;
// Free resources.
private void FreeResources(bool freeManagedResources)
{
Console.WriteLine(Name + ": FreeResources");
if (!ResourcesAreFreed)
{
// Dispose of managed resources if appropriate.
if (freeManagedResources)
{
// Dispose of managed resources here.
Console.WriteLine(Name + ": Dispose of managed resources");
}
// Dispose of unmanaged resources here.
Console.WriteLine(Name + ": Dispose of unmanaged resources");
// Remember that we have disposed of resources.
ResourcesAreFreed = true;
}
}
}
99% of the time, you should not have to worry about either. :) But, if your objects hold references to non-managed resources (window handles, file handles, for example), you need to provide a way for your managed object to release those resources. Finalize gives implicit control over releasing resources. It is called by the garbage collector. Dispose is a way to give explicit control over a release of resources and can be called directly.
There is much much more to learn about the subject of Garbage Collection, but that's a start.
The finalizer is for implicit cleanup - you should use this whenever a class manages resources that absolutely must be cleaned up as otherwise you would leak handles / memory etc...
Correctly implementing a finalizer is notoriously difficult and should be avoided wherever possible - the SafeHandle class (avaialble in .Net v2.0 and above) now means that you very rarely (if ever) need to implement a finalizer any more.
The IDisposable interface is for explicit cleanup and is much more commonly used - you should use this to allow users to explicitly release or cleanup resources whenever they have finished using an object.
Note that if you have a finalizer then you should also implement the IDisposable interface to allow users to explicitly release those resources sooner than they would be if the object was garbage collected.
See DG Update: Dispose, Finalization, and Resource Management for what I consider to be the best and most complete set of recommendations on finalizers and IDisposable.
Diff between Finalize and Dispose methods in C#.
GC calls the finalize method to reclaim the unmanaged resources(such as file operarion, windows api, network connection, database connection) but time is not fixed when GC would call it. It is called implicitly by GC it means we do not have low level control on it.
Dispose Method: We have low level control on it as we call it from the code. we can reclaim the unmanaged resources whenever we feel it is not usable.We can achieve this by implementing IDisposal pattern.
The summary is -
You write a finalizer for your class if it has reference to unmanaged
resources and you want to make sure that those unmanaged resources
are released when an instance of that class is garbage collected
automatically. Note that you can't call the Finalizer of an object explicitly - it's called automatically by the garbage collector as and when it deems necessary.
On the other hand, you implement the IDisposable interface(and
consequently define the Dispose() method as a result for your class) when your class
has reference to unmanaged resources, but you don't want to wait for
the garbage collector to kick in (which can be anytime - not in
control of the programmer) and want to release those resources as
soon as you are done. Thus, you can explicitly release unmanaged resources by calling an object's Dispose() method.
Also, another difference is - in the Dispose() implementation, you should release managed resources as well, whereas that should not be done in the Finalizer. This is because it's very likely that the managed resources referenced by the object have already been cleaned up before it's ready to be finalized.
For a class that uses unmanaged resources, the best practice is to define both - the Dispose() method and the Finalizer - to be used as a fallback in case a developer forgets to explicitly dispose off the object. Both can use a shared method to clean up managed and unmanaged resources :-
class ClassWithDisposeAndFinalize : IDisposable
{
// Used to determine if Dispose() has already been called, so that the finalizer
// knows if it needs to clean up unmanaged resources.
private bool disposed = false;
public void Dispose()
{
// Call our shared helper method.
// Specifying "true" signifies that the object user triggered the cleanup.
CleanUp(true);
// Now suppress finalization to make sure that the Finalize method
// doesn't attempt to clean up unmanaged resources.
GC.SuppressFinalize(this);
}
private void CleanUp(bool disposing)
{
// Be sure we have not already been disposed!
if (!this.disposed)
{
// If disposing equals true i.e. if disposed explicitly, dispose all
// managed resources.
if (disposing)
{
// Dispose managed resources.
}
// Clean up unmanaged resources here.
}
disposed = true;
}
// the below is called the destructor or Finalizer
~ClassWithDisposeAndFinalize()
{
// Call our shared helper method.
// Specifying "false" signifies that the GC triggered the cleanup.
CleanUp(false);
}
The best example which i know.
public abstract class DisposableType: IDisposable
{
bool disposed = false;
~DisposableType()
{
if (!disposed)
{
disposed = true;
Dispose(false);
}
}
public void Dispose()
{
if (!disposed)
{
disposed = true;
Dispose(true);
GC.SuppressFinalize(this);
}
}
public void Close()
{
Dispose();
}
protected virtual void Dispose(bool disposing)
{
if (disposing)
{
// managed objects
}
// unmanaged objects and resources
}
}
The main difference between Dispose and Finalize is that:
Dispose is usually called by your code. The resources are freed instantly when you call it. People forget to call the method, so using() {} statement is invented. When your program finishes the execution of the code inside the {}, it will call Dispose method automatically.
Finalize is not called by your code. It is mean to be called by the Garbage Collector (GC). That means the resource might be freed anytime in future whenever GC decides to do so. When GC does its work, it will go through many Finalize methods. If you have heavy logic in this, it will make the process slow. It may cause performance issues for your program. So be careful about what you put in there.
I personally would write most of the destruction logic in Dispose. Hopefully, this clears up the confusion.
Class instances often encapsulate control over resources that are not managed by the runtime, such as window handles (HWND), database connections, and so on. Therefore, you should provide both an explicit and an implicit way to free those resources. Provide implicit control by implementing the protected Finalize Method on an object (destructor syntax in C# and the Managed Extensions for C++). The garbage collector calls this method at some point after there are no longer any valid references to the object.
In some cases, you might want to provide programmers using an object with the ability to explicitly release these external resources before the garbage collector frees the object. If an external resource is scarce or expensive, better performance can be achieved if the programmer explicitly releases resources when they are no longer being used. To provide explicit control, implement the Dispose method provided by the IDisposable Interface. The consumer of the object should call this method when it is done using the object. Dispose can be called even if other references to the object are alive.
Note that even when you provide explicit control by way of Dispose, you should provide implicit cleanup using the Finalize method. Finalize provides a backup to prevent resources from permanently leaking if the programmer fails to call Dispose.
I searched the answer to this question a lot today. I will share my learnings here. My answer is based on this link, because it has the clearest explanation I have seen.
When your objects has access to unmanaged resources, you have to manually release those resources. This can be done via IDisposable or finalizer meaning they both release unmanaged resources.
Rule of thumb:
Implement IDisposable to release unmanaged resources and caller code must call Dispose method. If caller forgets to call Dispose() method, you still can provide a method to release those unmanaged resources. First option is using safe handle to wrap unmanaged resource. Second option is defining a finalizer. Using safe handle is recommended way in this case.
I think this link is the clearest answer to this question. I do not know why people provide complex explanations to this question on the internet. It made me feel confused until I find that link.
As we know dispose and finalize both are used to free unmanaged resources..
but the difference is finalize uses two cycle to free the resources , where as dispose uses one cycle..
To answer on the first part you should provide examples where people use
different approach for the exact same class-object.
Otherwise it is difficult (or even strange) to answer.
As for the second question better read first this
Proper use of the IDisposable interface
which claims that
It's your choice! But choose Dispose.
In other words: The GC only knows about finalizer (if any. Also known as destructor to Microsoft).
A good code will attempt to cleanup from both (finalizer and Dispose).

Categories

Resources