Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Should IDisposable be applied cascadingly?

This is a rather basic question, however I'm still struggling with it a little.

IDisposable is implemented, when you want to enable the user of an object to free underlying resources (e.g. sockets etc.) before the object is eventually garbage collected.

When i have a class that holds a DbConnection (implements IDisposable), does my class need to implement IDisposable too and chain the call down to the DbConnection or any other IDisposable objects it owns? Else the DbConnections resources will only be freed when my class is GarbageCollected, thereby drops it reference to the connection and GC will finalize the DbConnection.

like image 226
Johannes Rudolph Avatar asked Sep 22 '09 17:09

Johannes Rudolph


People also ask

When should you use IDisposable?

You should implement IDisposable when your class holds resources that you want to release when you are finished using them. Show activity on this post. When your class contains unmanaged objects, resources, opened files or database objects, you need to implement IDisposable .

Should I implement both IDisposable and IAsyncDisposable?

Implement both dispose and async dispose patternsYou may need to implement both the IDisposable and IAsyncDisposable interfaces, especially when your class scope contains instances of these implementations. Doing so ensures that you can properly cascade clean up calls.

Why should we implement IDisposable?

in a class, you should implement IDisposable and overwrite the Dispose method to allow you to control when the memory is freed. If not, this responsibility is left to the garbage collector to free the memory when the object containing the unmanaged resources is finalized.

What happens if you dont Dispose IDisposable?

IDisposable is usually used when a class has some expensive or unmanaged resources allocated which need to be released after their usage. Not disposing an object can lead to memory leaks.


1 Answers

Yes, you ALWAYS implement IDisposable if you control disposable objects. ALWAYS. Your code won't break if you don't, but it defeats the purpose of having disposable objects if you don't.

The general rule for GC optimization is:

  • Any class that controls objects not managed by the GC must implement a finalizer (and generally should implement IDisposable as well). This is where the "top level" disposable classes usually come from -- they usually control a HANDLE to a window, socket, mutex, or what have you.
  • Any class that instantiates an IDisposable member should implement IDisposable itself, and properly Dispose() of its constituents.
  • Any function that instantiates an IDisposeable object should properly Dispose() of it when it done being used. Don't let it just drop out of scope.

These rules may be bent or ignored if you're writing an application for yourself, but when distributing code to others you should be professional and follow the rules.

The logic here is that when you control memory outside the view of the GC the GC engine can't properly manage your memory usage. On your .NET heap, for example, you may just have a 4-byte pointer, but out in unmanaged land you could have 200 MB of memory being pointed at. The GC engine wouldn't attempt to collect these until you have several dozen, because all it sees is a few bytes; while in the real world it looks a lot like a memory leak.

Therefore, the rule is, unmanaged memory should get freed immediately when you're done using it (the IDisposable chain does this for you), while managed memory gets freed by the GC engine whenever it gets around to it.

like image 188
tylerl Avatar answered Sep 25 '22 23:09

tylerl