Few difficult for me questions about Dispose()

P

Piotrekk

Hi

I have few questions which I would like to ask:

1. When would I place my own code to Form1 : Form method
2. When would I create Dispose method by implementing IDispose - what
is the example scenario. If so, why is better than doing something
different / simpler

What I am trying to understand is the reason for IDisposable
interface. Does implementing this interface really introduces
benefits?
When I work with the data I never really use Dispose - maybe should I
in some cases?

Best Regards
Piotr Ko³odziej
 
P

Peter Morris

Anything managed is collected automatically so most of the time you don't
need it. What if for example you had a class like FileStream which uses API
to create a windows handle, then you need to dispose of those resource when
your object is collected. IDispose gives the programmer to opportunity to
release the resources immediate rather than having to wait for a garbage
collection. E.G.


for (int i = 0; i < 100000; i++)
{
using (new FileStream.............)
{
}
}


"using" will call FileStream.Dispose for each loop. If you didn't have
"using" then Dispose would not be called and you would have more than 1 open
file.


You can also use this for non-managed things. For example you might have an
object that holds a dictionary

Dictionary<string, MyClass> objectByName = new Dictionary<string,
MyClass>();

as time goes on you add more and more items to this dictionary using up more
and more memory. When you have finally finished with your object why wait
until it is collected before its dictionary is freed when you could
implement IDisposable and clear it?



Pete
 
T

Tom

I certainly can relate to your questions!!

I posted recently on similar topic and got some wonderful replies from
some of the many gurus who frequent here. Their explanations were of
great help to me. I suggest reading the following thread because I
can't explain it any better than those who helped me out.

FileStream.Close() & GarbageCollection - Memory Leak Question

The above topic was posted on 2/4/08.

I hope it helps. :)

-- Tom
 
N

Nicholas Paldino [.NET/C# MVP]

Piotr,

1 - Form1 : Form looks like a part of a class declaration. Are you asking
when you would place code in the Dispose method on that class? Usually, if
you have a class-level variable which implements IDisposable, you would make
calls to those implementations of IDisposable in your implementation of
Dispose. See the section of the MSDN documentation titled "Implementing
Finalize and Dispose to Clean Up Unmanaged Resources" located at:

http://msdn2.microsoft.com/en-us/library/b1yfkh5e(vs.71).aspx

Specifically, you want to look at the Derived class in the example, as
your Form1 class derives from an implementation of IDisposable already.

2. You would implement IDisposable from scratch if you were accessing a
resource which required explicit cleanup. Things that fall in this category
are file handles, sockets, database connections, unmanaged memory pointers,
etc, etc. Not when you use ^managed^ wrappers around them, but when you are
accessing the handles/pointers themselves.

If you are using data classes, especially connections, I wouldn't be so
worried about implementing IDisposable unless you are storing things like a
connection on the class level which would require your class to implement
IDisposable and have its Dispose method called when your class is done being
used.


--
- Nicholas Paldino [.NET/C# MVP]
- (e-mail address removed)

Hi

I have few questions which I would like to ask:

1. When would I place my own code to Form1 : Form method
2. When would I create Dispose method by implementing IDispose - what
is the example scenario. If so, why is better than doing something
different / simpler

What I am trying to understand is the reason for IDisposable
interface. Does implementing this interface really introduces
benefits?
When I work with the data I never really use Dispose - maybe should I
in some cases?

Best Regards
Piotr Ko³odziej
 
P

Piotrekk

First of all - thank You all.

Regarding to what Peter said:

Why have you written that Dictionary is non-managed example? Since
this is .net class it should be managed .



And what particularly would you put inside Dispose() method ?
I am really interested in your answer at this point.
I would just call Clear method ( and depending of how items are
removed ( I couldn't find answer how Clear exactly works but I assume
it just clears all references to items allocated on heap memory )
eventually call GC.Collect()
What do you think?
 
P

Piotrekk

1 - Form1 : Form looks like a part of a class declaration. Are you asking
when you would place code in the Dispose method on that class? Usually, if
you have a class-level variable which implements IDisposable, you would make
calls to those implementations of IDisposable in your implementation of
Dispose. See the section of the MSDN documentation titled "Implementing
Finalize and Dispose to Clean Up Unmanaged Resources" located at:

Does it mean that when i work with just Form1 : Form class, and I use
some unmanaged resources ( files in WINAPI for example ) I should
release these resources in overriden Dispose() method?
I have also heard that unmanaged resource can be for example a socket.
How could this be? Socket is also .net class so it should be fully
managed. Or did they mean socket - but when using API ?
 
P

Peter Morris

Why have you written that Dictionary is non-managed example? Since
this is .net class it should be managed .

I meant to say that you needn't use this ONLY for non-managed things :)
 
J

Jon Skeet [C# MVP]

I meant to say that you needn't use this ONLY for non-managed things :)

But unless you explicitly call GC.Collect() (which is generally a bad
idea) you won't achieve anything by calling Dispose. Dispose doesn't
free the object from memory, it's just meant to release unmanaged
resources. It *might* set a few member variables to null so that in
particularly rare cases (where the object itself is in gen1 but it has
references to gen0 objects, for instance) memory will become available
earlier - but that's unlikely.
 
C

Cor Ligthert[MVP]

Piotrekk,

Managed code can use unmanaged resources.

(I have never seen a good descriptiojn what is an unmanaged resource,
however as long as you not are using a form by coding that without any
version of Visual Studio (including express versions), then the disposing of
components is included in the code that is created when you add it to the
designer). However AFAIK can by instance a Dialog form better be disposed
direct, as it implements very old resources, the same for pens and other
drawing compenents, while that are often using so many resources that you
can reach the end of the maximum to use resources).

Cor
 
P

Peter Morris

But unless you explicitly call GC.Collect() (which is generally a bad
idea) you won't achieve anything by calling Dispose.

That's not true. It might be the case that you have references to this
object from places which will remain in place for quite some time, E.G. in a
form or a static member. Sure this is a mistake but by having some kind of
cleanup on classes which hold onto a lot of memory you will at least allow
the GC to collect the data it no longer requires.

free the object from memory, it's just meant to release unmanaged
resources. It *might* set a few member variables to null so that in
particularly rare cases (where the object itself is in gen1 but it has
references to gen0 objects, for instance) memory will become available
earlier - but that's unlikely.

If my class has a dictionary<string, object> which allows me to look up an
object from a cache by some ID I can easily hold onto
A: A big chunk of data in the form of strings ( a few million for example)
B: A whole load of referenced objects

Now if I have a form that holds a reference to my object for too long, or I
make the mistake of holding a reference in a static variable etc, then by
disposing the object I will
A: Allow this memory to be reclaimed
B: Identify the object as disposed, and when (maybe under rare
circumstances) the reference holding code tries to use the object an
exception will occur (if you implement it correctly) informing you of the
problem.

I think it's good practise in situations like this because it releases
memory earlier and in addition helps you to find a bug which you might not
otherwise notice. For example in my object persistence framework I use
IDisposable to ensure that my LoadedObjectCache Dictionary<> unloads all
cached objects when I have finished with my "object space". Why? Why not!
I get the memory back quicker, and if I try to use the object afterwards due
to some erroneous code where I still have a reference but really shouldn't
then I get an ObjectDisposedException. As my OPF was designed for the
compact framework I find it additionally beneficial.


Pete
 
P

Peter Morris

(I have never seen a good descriptiojn what is an unmanaged resource,

If you use WinAPI to create a Mutex for example, or a file handle, or a
socket, then those are unmanaged resources. When your class instance dies
the handle will not automatically be released. Many of these have .NET
wrapper classes already (FileStream for example) which implement IDisposable
and correctly release the handles.

A good example would be if you know there is a WinAPI to do something but no
..NET class equivalent. You might write a .NET wrapper class to talk to the
API. As a result you would implement a Finalizer on the class in order to
clean up any "unmanaged" resources, and if you are well behaved you will
also implement IDisposable so that the user of your class may release the
resources at a specific point in time :)



Pete
 
J

Jon Skeet [C# MVP]

That's not true. It might be the case that you have references to this
object from places which will remain in place for quite some time, E.G. in a
form or a static member. Sure this is a mistake but by having some kind of
cleanup on classes which hold onto a lot of memory you will at least allow
the GC to collect the data it no longer requires.

Calling Dispose() won't clear those references unless you explicitly
make it do so though. I can't remember ever seeing *that* particular
situation - where the class itself knew where it was used
inappropriately.

You can clear your own references, but I personally think that's a poor
use of IDisposable.
If my class has a dictionary<string, object> which allows me to look up an
object from a cache by some ID I can easily hold onto
A: A big chunk of data in the form of strings ( a few million for example)
B: A whole load of referenced objects

Now if I have a form that holds a reference to my object for too long, or I
make the mistake of holding a reference in a static variable etc, then by
disposing the object I will
A: Allow this memory to be reclaimed
B: Identify the object as disposed, and when (maybe under rare
circumstances) the reference holding code tries to use the object an
exception will occur (if you implement it correctly) informing you of the
problem.

What exactly does your Dispose method do here? Just set the member
variable to null?

Unless there's a real *need* to implement IDisposable, I don't like
putting the burden on callers.
I think it's good practise in situations like this because it releases
memory earlier and in addition helps you to find a bug which you might not
otherwise notice. For example in my object persistence framework I use
IDisposable to ensure that my LoadedObjectCache Dictionary<> unloads all
cached objects when I have finished with my "object space". Why? Why not!
I get the memory back quicker, and if I try to use the object afterwards due
to some erroneous code where I still have a reference but really shouldn't
then I get an ObjectDisposedException. As my OPF was designed for the
compact framework I find it additionally beneficial.

Do you need to implement IDisposable for any direct/indirect unmanaged
resources? If not, the fact that you implement IDisposable solely in
case people misuse your object is going to make diligent callers do
extra work to call Dispose just in case you actually *do* do something
which is really required. In some cases that may mean implementing
IDisposable themselves, and may make other code harder to read.

I would rather work with the assumption that the data within my objects
is required while my objects themselves are required - and that when
they're not, those objects will become eligible for garbage collection,
along with whatever they reference (leaving aside shared references).
Garbage collection is designed around exactly that assumption - putting
in explicit releases is effectively saying it's not doing a good enough
job on its own.
 
C

Cor Ligthert[MVP]

Peter,

Sorry, I should have written
I never have seen a good *list* what are the most common unmanaged
resources.

Some are a little bit hidden you know, because as you wrote some classes are
just wrappers.

Cor
 
N

Nicholas Paldino [.NET/C# MVP]

Piotrekk,

Yes, if you are dropping down to the Windows API and have handles to a
file that are accessed in your form, then yes, you should add code to the
Dispose method implementation which takes a boolean parameter, and always
release the unmanaged resource in that code.

As for the Socket class, there is a representation in unmanaged code, as
well as a representation in managed code. Just like the file handle above,
you can access sockets with unmanaged code (through the Windows API) or
through the Socket class in the System.Net namespace (which implements
IDisposable, because in the end, it is accessing the Windows API and holding
onto that unmanaged handle).
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top