Home | Contact Us | FAQ | Search & Site Map | Link to Us
Sign In | Join | Other 45 Sites in Network
HomeAnnouncementsFree MagazinesWhite PapersSubmit Content
Discussion GroupsASP.NETWindows FormsLanguages.NET FrameworkVisual Studio.NET
Articles.NET FrameworkASP.NETToolsWindows Forms
.NET DirectoryOpen Source ProjectsUser GroupsWeb Resources
Related Topics
Visual Basic 6SQL ServerMS AccessOther DB ProductsMS Server ProductsMore Topics ...

.NET Forum / .NET Framework / CLR / December 2004

Tip: Looking for answers? Try searching our database.

Access managed member field in Finalizer

Thread view: 
Enable EMail Alerts  Start New Thread
Thread rating: 
Pros Van Dessel - 21 Dec 2004 21:18 GMT
Suppose you build a class that needs a temporary directory for its
operations:

class MyClass
{
   private string m_tempDir;
   public MyClass()
   {
       m_tempDir = @"C:\" + System.Guid.NewGuid().ToString();
       System.IO.Directory.CreateDirectory( m_tempDir );
   }
}

When an object of this type is instantiated, a temporary directory will be
created.  When the instance is garbage collected, I would like the directory
to disappear.  I'ts very tempting to add a finalizer to the class:

~MyClass()
{
   System.IO.Directory.Delete( m_tempDir );
}

***BUT*** as I understood, the order in which managed objects is
inpredictable so m_tempDir could be collected before the MyClass finalizer
code is executed.  This makes it illegal to access m_tempDir in the
finalizer.

So the question is: which pattern can be used to guarantee that the
temporary directory will be deleted when a MyClass instance is collected?

I don't want to rely on the client code to call some dispose method, I want
the class itself to make sure it cleans up the temp directory.  I also don't
like the idea of allocating some unmanaged memory to store the filename: in
my opinion, this does not result in .Net code as it is meant to be
written...

More generic: which pattern can be used if a finalizer needs to carry out
some clean-up actions (delete a file, stop a thread, stop sponsoring a
remote object,... ) that need access to other managed objects to which the
finalizing object holds the only reference?
David Browne - 21 Dec 2004 21:57 GMT
> Suppose you build a class that needs a temporary directory for its
> operations:
[quoted text clipped - 22 lines]
> inpredictable so m_tempDir could be collected before the MyClass finalizer
> code is executed.

No.  You are confusing Finalization with Garbage Collection.  Finalization
always occurs between garbage collections.  One garbage collection will
identify finalizable objects and queue them for finalization.  Then, after
they are finalized, a subsequent garbage collection will collect them.

All finalizable objects identified in a garbage collection are queued for
finalization.  The finalizer thread then runs each finalizer.  The order in
which the finalizers of are run is unpredictable, so you should not access
other finalizable objects in your finalizer.

Garbage collection for your finalizable object and for any object to which
your finalizable object has a reference is guaranteed not to happen until
after your finalizer runs, usually long, long after your finalizer has run.
Since your finalizer caused your object to survive GC, it has been promoted
and it will linger on the managed heap until the next collection of it's new
generation.

>This makes it illegal to access m_tempDir in the finalizer.

m_tempDir is fine because System.String does not have a finalizer.  When
~MyClass runs, the MyClass instance and all objects it references (and all
objecects they reference, etc) are still allocated on the managed heap.
They have all been promoted, and will not be collected until the _next_
garbage collection of their new generation.  If any other object in this
graph has a finalizer, that finalizer may run either before or after
~MyClass.  If the finalizer on the referenced object has already run, it is
likely to be in an unusable state and may generate an exception or do
something unpredictable if you try invoking its methods from inside
~MyClass.

> So the question is: which pattern can be used to guarantee that the
> temporary directory will be deleted when a MyClass instance is collected?
>
> I don't want to rely on the client code to call some dispose method, I
> want the class itself to make sure it cleans up the temp directory.

In addition to the finalizer, you should implement the Disposable pattern.
Either just Dispose, or Dispose and a Finalizer: never just a finalizer.

Dispose should delete the directory, and then call GC.SupressFilalize(this).
This will prevent your finalizer from running _if_ the client remembers to
call dispose.  The finalizer is then just a backup.  You want to let Dispose
clean up your objects whenever possible since having a finalizer forces your
object and all the objects it references to be promoted to later generation
and disposed much later.  This can significantly add to the memory
utilization of your application and cost you more time in garbage
collection.

David
Jon Skeet [C# MVP] - 21 Dec 2004 22:03 GMT
> Suppose you build a class that needs a temporary directory for its
> operations:
[quoted text clipped - 22 lines]
> code is executed.  This makes it illegal to access m_tempDir in the
> finalizer.

No. The variable definitely can't be garbage collected - but it may
have been finalized. If you know that string doesn't have a finalizer
(I don't know either way, to be honest) then you can use it.

> So the question is: which pattern can be used to guarantee that the
> temporary directory will be deleted when a MyClass instance is collected?
[quoted text clipped - 4 lines]
> my opinion, this does not result in .Net code as it is meant to be
> written...

Be aware that the finalizer may not be run, in certain situations.

Signature

Jon Skeet - <skeet@pobox.com>
http://www.pobox.com/~skeet
If replying to the group, please do not mail me too


Rate this thread:







Free Magazines

Get these publications absolutely FREE for up to 12 months. There are no hidden fees and no obligation. Simply choose a title, complete the application form and submit it. Read more ...

Oracle MagazineNetwork ComputingComputer WorldBio-IT WorldeWeekInformation WeekInfosecurity
 
Sign In
Join
My Latest Posts
My Monitored Threads
My Blog
My Photo Gallery
My Profile
My Homepage

Start New Thread
Enable EMail Alerts
Rate this Thread



©2008 Advenet LLC   Privacy Policy - Terms of Use
This website includes both content owned or controlled by Advenet as well as content owned or controlled by third parties.