Lars1346

Hi,

Apologise if this is the wrong forum.

I have a few queries regarding Destructor, Finalize and Dipose which is causing me some confussion (c++ background).

Its my understanding that any destructor made in source code gets converted to a Finalizer (including try finally statements) by the compiler. Hence, there is never any reason for me to explicitly create or call a Finalize method

What is the definition for managed and for unmanaged resources. I've read that unmanaged resources is file handles, gdi objects, database connections but what is then an managed resource Is objects on the heap an managed resource

So the destructor is an implicit way to cleanup an object and Dispose is an explicit way

When do I need a destructor, IDisposable or both in a class

This I'm guessing wont require either;

Code Snippet

public class foo

{

private string _somevalue;

}

But what about this;

Code Snippet

public class foo

{

Font f = new Font("Somefont",12);

}

Is there any rule of dumb or guidelines to follow

Furthermore is the purpose of the destructor and IDisposable to release both managed and unmanaged resource or just unmanaged resources

Appreciate any input on the matter.



Re: Common Language Runtime Destructor and dispose

Alois

Unmanaged resources are all unmanaged objects which require explicit cleanup such as OS handles which include fonts, mutexes, files, sockets, semaphores, named pipes, ....

If an unmanaged resource is encapsulated by a class (e.g. Font) which already implements a finalizer you must not write inside your class a finalizer which does contain font objects. But you should provide a Dispose method to enable a deterministic resource maangement for the callers of your class. Finalizers can be called or not and you never know when they are called. You only know that the finalizer will be called some time after no one references your class.

The only reason to write a finalizer is that if you have your own handles allocated inside your class. With .NET 2.0 this is not so much needed since there were many SafeXXXHandle classes introduced which wrap most OS handle types. They provide a dispose method and a finalizer if nobody did care to close the handle.

In 90% of all cases you will be fine with the Dispose pattern where you have the obligation to call dispose on all class members you have as members inside your class to ensure good cleanup.

The other 10% you will want to write a finalizer AND always provide dispose method. Otherwise the users will have a hard time to close and reopen a file when you only rely on finalizers which are executed in a non deterministic way.

Yours,
Alois Kraus





Re: Common Language Runtime Destructor and dispose

Rob Teixeira

Unmanaged resources are any resources that are handled by non-.NET code, most of them come from the operating system. They typically have a handle that must be used to close the resource when it's no longer used.

Any code in the .NET framework, .NET code that you write, and .NET code in 3rd party libraries are managed (managed by the .NET Common Language Runtime). The runtime contains many managed wrappers (.NET wrapper code) for unmanaged (OS) resources. The managed wrappers typically implement IDisposable and have finalizers.

C# uses the C++ destructor-style syntax to create finalizer methods. Just be careful not to raise exceptions in that code.

The problem with finalizers is that you have no idea when they will run because the runtime uses garbage collection. Unused objects just sit in memory until the GC decides to clean them up. This is what is called undeterministic finalization. IDisposable is an interface that enforces a Dispose method on the object. People using your classes can then explicitly call Dispose to free up resources (assuming your object needs to free them up). This allows them to control when the freeing occurs (more info here on how to implement IDisposable: http://msdn2.microsoft.com/en-us/library/b1yfkh5e.aspx) instead of waiting until the GC gets around to calling the finalizer. It's possible that GC will never run for the life of the app, so resources could remain open until the app closes down, and that's why using a Dispose method when it's available is important. So your analogy of implicit and explicit is fairly accurate.

Whenever you instantiate a class that implements IDisposable, you almost always have to call Dispose to avoid some resource being kept open for too long. There are a few exceptions, like non-modal Windows forms that automatically dispose when they are closed. Some objects also have a Close method (like certain types of streams) which perform the same thing as Dispose, but the object still implements IDisposable. Also note that for local resource usage, the Using block is pretty handy because it will automatically dispose the object it's using at the end of the block even if an exception is raised.

Typically, you won't need to release managed resources. That's the point of having GC in the first place (and you shouldn't force GC cleanup either). The only times I have used Dispose for managed resources is when I wrote some cryptography utilities that zeroed out managed data arrays when they were no longer used.






Re: Common Language Runtime Destructor and dispose

Lars1346

Thanks for both replies.

Alois wrote:

In 90% of all cases you will be fine with the Dispose pattern where you have the obligation to call dispose on all class members you have as members inside your class to ensure good cleanup.

Wouldnt it be wise to use both Finalizer and Dipose, I mean in case the programmer 'forgets' to run Dispose Sort of a safe-guard.

Given this code, from linked posted above; Where would I place a member variable of type Font below I suppose Font is an wrapper class for an unmanaged resource but does that make it an managed or unmanaged object \ resource What does the last sentence mean (set large fields to null) I mean, is this to remove a reference to the objects And why only large fields

Code Snippet
protected virtual void Dispose(bool disposing)
{
if (disposing)
{
// Free other state (managed objects).
}
// Free your own state (unmanaged objects).
// Set large fields to null.
}

Another thing from the link;

"Do not make the Finalize method more visible. It should be protected, not public."

I thought Finalize (or destructor) did not have an visibility assigned. i.e. ~Base().







Re: Common Language Runtime Destructor and dispose

Rob Teixeira

Yes, if you implement Dispose, you must also implement a finalizer. The Dispose method simply gives the programmer an explicit and timely way of closing necessary resources. But if the programmer forgets to call Dispose, the resource must still be closed.

The Font object is a .NET managed object that wraps an operating system unmanaged resource. That means it's a .NET object that contains a font handle created by the OS and delegates operations of that OS font handle through .NET methods. It implements IDisposable because the underlying OS font handle must be closed at some point by using the CloseHandle OS call.

In C#, the finalizer does not have an explicit visibility, but one is assigned by the compiler for you, so you don't have to worry about it.






Re: Common Language Runtime Destructor and dispose

Lars1346

Thanks for your input.

So unmanaged resources means for instance HANDLE, HWND, HICON, FILE etc.

The general pattern for cleaning up resources in C# is,

  • Finalizer - unmanaged resources
  • Dispose - unmanaged and managed resources

In a project I'm involved with atm we do not use unmanaged resources directly, only through wrapped .NET classes. So there is actually no need for a destructor (finalizer) when there are no unmanaged resources. I would also think that given the huge number of wrapped .NET classes available in .NET 2.0 there is a decreasing need to implement a destructor at all.





Re: Common Language Runtime Destructor and dispose

Rob Teixeira

That is correct, there shouldn't be a big need to create finalizers. The whole point of having a memory managed environment is to aleviate the need to worry about those things.

If you are not dealing directly with unmanaged resources, the only time you might have to worry about finalizers and implementing Dispose is when you hold on to an open wrapper instance at a global or class level (beyond just one immediate function, where you would otherwise make use of a Using statement).






Re: Common Language Runtime Destructor and dispose

Greg Beech

I wrote a fairly comprehensive guide to IDisposable and finalizers a while back: http://gregbeech.com/blogs/tech/archive/2007/03/07/implementing-and-using-the-idisposable-interface.aspx

It should cover everything you need to know. If not, let me know and I'll extend it or write a follow up.






Re: Common Language Runtime Destructor and dispose

Lars1346

Thats an excellent article Greg. Best I've read on the subject.

Thanks for the help guys.