Re: Lowdown on finalization

From: Tom Shelton (tom_at_mtogden.com)
Date: 02/03/04


Date: Tue, 03 Feb 2004 07:36:27 -0800

On 2004-02-03, Frank Rizzo <nospam@nospam.com> wrote:
> Tom Shelton wrote:
>> On 2004-02-03, Frank Rizzo <nospam@nospam.com> wrote:
>>
>>>Tom Shelton wrote:
>>>
>>>>On 2004-02-03, Frank Rizzo <nospam@nospam.com> wrote:
>>>>
>>>>
>>>>>Can someone give a reader's digest on finalization of objects in .net
>>>>>framework.
>>>>>
>>>>>When do I need to call .Dispose?
>>>>
>>>>When your object manages unmanaged resources (ex: Database connections,
>>>>sockets, file handles, os handles, etc). In these cases you'll want
>>>>your class to implement the IDisposable interface...
>>>
>>>So implementing this interface means what? That when the client calls
>>>.Dispose method on my object, I'll release whatever needs to be released?
>>>
>> Yep.
>>
>>
>>>How is that different from writing a ReleaseResources method where I
>>>release all the resources?
>>>
>> There is no difference. IDisposable is just a formalized interface to
>> accomplish this. Basically, it is a convention.
>
> Ah, I got it.
>
>>>>And of course, you'll want to call it on any class that implements it :)
>>>>>What happens when I set the object to Nothing (or null in c#)
>>>
>>>So should I set local objects to Nothing or not? What about class level
>>>variables that I no longer need?
>>>
>> Local objects don't need to be set to nothing because once the object is
>> out of scope and no longer referenced it is eligable for GC. In fact,
>
>
> Ok, let's take 2 concrete examples with an object holding an actual
> resource.
>
> private sub MySub()
> dim o as Sqlconnection = new SqlConnection("server=x;userid=sa")
> o.Open
>
> 'do stuff
> o.Execute ("drop master")
> end sub
>
> Am I right in thinking that GC may not immediately kill the o
> (SqlConnection) object, leaving the connection to the database open for
> undetermined amount of time?
>
>
> Assuming I am correct, I'd need to do the following:
>
> ...
> o.Close
> o.Dispose
> end Sub
>
> Correct?
>

Correct, except in this case the Dispose is redundant... o.Close
basically does the same thing - release the connection :)

>
> Second example, this time in pseudo-code
>
> private sub MySub2()
> dim oFile as File = new File("c:\autoexec.bat")
> oFile.Open modeExclusiveWrite
>
> oFile.Append ("some extra text")
>
> oFile = Nothing
> end sub
>
> In this case, if someone else tried open c:\autoexec.bat, they would
> fail because the file is opened for exclusive write and setting oFile to
> Nothing has no immediate effect.
>

Exactly

> In other words, the proper way to do it would be manually call the
> Dispose method on the oFile object (i am assuming such a method exists).
>

Dispose or Close.

> Am I right in my assumptions?
>

Pretty much. GC is indeterminate

>>>Also, how is Finalize different?
>>>
>>
>>
>> Finalize is a method of object. It's purpose is essentially the same as
>> Dispose - release resources. The difference is that Finalize is called
>> by the GC, and should be avoided because it can have a negative impact
>> on the performance of the GC, because it actually takes two passes to
>> clean up an object that has overridden Finalize.
>>
>> What you will usually see is that objects that contain unmanaged
>> resources will usually implement both IDisposable AND override finalize.
>> The Dispose implementation, will usually call GC.SuppressFinalize to
>> remove the object from the finalization queue. This way, you can make
>> sure that your resources will be released eventually - even if the
>> client forgets to call dispose. But if they do remember, then you don't
>> incure the performance hit.
>>
>> One thing I've taken to doing lately, is actually throw an exception
>> from the finalize method (or you could use an assertion). This sort of
>> clues me in to when I haven't managed my resources properly :)
>
> Ok, so I am confused again. What should be I cleaning up in Finalize,
> if all my resources were released in Dispose?

The same resources you cleaned up in Dispose... Think of it as a back
stop. If the client forgets to call Dispose, then you know that your
resources will get cleaned up - eventually.

Jay, gave some pretty good links on the subject - they may be able to
explain it a little clearer...

-- 
Tom Shelton [MVP]
Powered By Gentoo Linux 1.4
"He dropped his voice still lower. In the stillness, a fly 
would not have dared cleat its throat. " 


Relevant Pages

  • Re: Lowdown on finalization
    ... Because the method no longer referes to o, ... Finalize is a method of object. ... Dispose - release resources. ...
    (microsoft.public.dotnet.languages.vb)
  • Re: Dispose, Finalize
    ... Wenn Ihr sagt, das Finalize Dispose ... > Public Sub Dispose ... ... > End Sub ...
    (microsoft.public.de.german.entwickler.dotnet.vb)
  • Re: Garbage Collection
    ... If you can explicitly call Dispose, it is always best to do this as this ... provides timely release of resources the object may be holding onto. ... > Sub Internal1() ...
    (microsoft.public.dotnet.languages.vb)
  • Re: Lowdown on finalization
    ... >>How is that different from writing a ReleaseResources method where I ... Dispose method on the oFile object. ... > Dispose - release resources. ... The difference is that Finalize is called ...
    (microsoft.public.dotnet.languages.vb)
  • Re: Automatic Dispose
    ... But, a SqlConnection itselft is a managed resource and, as such, should not ... instance user uses "Using" and Dispose is called automatically). ... Public Overridable Sub Dispose() Implements IDisposable.Dispose ... Protected Overrides Sub Finalize() ...
    (microsoft.public.dotnet.languages.vb)

Loading