How to dispose a dataset completely

A

Atul

Hi,

Once a dataset is populated from DataAdapter, I want to release the
memory acquired by dataSet object. So I call oDataSet.Dispose(). But
it doesnot disposes the internal objects like Datatable/dataColumn.

Should I have to call Dispose() method for these internal objects
explicitely? OR DataSet.Dispose() takes care to clear the internal
objects?

Thanx,
Atul
 
J

Joyjit Mukherjee

Hi,

The Garbage Collector for .NET runs in an undeterministic mode, means you
can't guarantee when precisely objects will be collected. But once you call
the dispose method of an object, make sure it will be collected. And you are
not supposed to call the dispose() methods of the inner objects, they are
call automatically.

Thanks
Joyjit
 
M

Miha Markic [MVP C#]

Joyjit Mukherjee said:
Hi,

The Garbage Collector for .NET runs in an undeterministic mode, means you
can't guarantee when precisely objects will be collected. But once you
call
the dispose method of an object, make sure it will be collected. And you
are
not supposed to call the dispose() methods of the inner objects, they are
call automatically.

Just to be sure, Dispose() doesn't mean that the object will be collected or
not.
It just means that it will dispose all resources it holds immediately.
It will be collected regardless of Dispose.
 
S

Scott M.

You really don't need to bother disposing a DataSet (or any other .NET
object for that matter) unless the object is holding on to unmanaged
resources that need to be manually cleaned up when you are done using the
object. This is the whole point of the Garbage Collector.
 
M

Miha Markic [MVP C#]

How do you know if the class is holding unmanaged resources?
You should call Dispose on every instance to relase resources asap.
Plus, you don't know what the future changes might be.
So, call Dispose on anything that implements IDisposable asap.
 
S

Scott M.

It's not difficult to know if an object is holding unmanaged resources since
the user of the object will be the one who "connected" the object to the
resource in the first place.

The whole point of garbage collection is to take the process of managing of
memory away from the developer. Dispose is simply a method call that *some*
(not all) classes have that is a good place to do clean up work with
unmanaged resources. Calling Dispose on anything that implements
IDisposable will result in a lot of unnecessary method calls. Your advice
is cautionary, but not realistic, efficient or necessary.


Miha Markic said:
How do you know if the class is holding unmanaged resources?
You should call Dispose on every instance to relase resources asap.
Plus, you don't know what the future changes might be.
So, call Dispose on anything that implements IDisposable asap.

--
Miha Markic [MVP C#] - RightHand .NET consulting & development
SLODUG - Slovene Developer Users Group
www.rthand.com

Scott M. said:
You really don't need to bother disposing a DataSet (or any other .NET
object for that matter) unless the object is holding on to unmanaged
resources that need to be manually cleaned up when you are done using the
object. This is the whole point of the Garbage Collector.
 
A

Alvin Bruney [MVP]

That is not correct for the reasons given in the previous thread. That
defeats the purpose of a managed environment.

--
Regards,
Alvin Bruney
[ASP.NET MVP http://mvp.support.microsoft.com/default.aspx]
Got tidbits? Get it here... http://tinyurl.com/27cok
Miha Markic said:
How do you know if the class is holding unmanaged resources?
You should call Dispose on every instance to relase resources asap.
Plus, you don't know what the future changes might be.
So, call Dispose on anything that implements IDisposable asap.

--
Miha Markic [MVP C#] - RightHand .NET consulting & development
SLODUG - Slovene Developer Users Group
www.rthand.com

Scott M. said:
You really don't need to bother disposing a DataSet (or any other .NET
object for that matter) unless the object is holding on to unmanaged
resources that need to be manually cleaned up when you are done using the
object. This is the whole point of the Garbage Collector.
 
S

Scott M.

One other thought on this in particular:
Plus, you don't know what the future changes might be.

Code should, for sure, be scallable. But, there is a point where you are
sacraficing efficiency for scalability. This is why good classes are those
that provide the *minimum* functionality based on design specs, rather than
building "mega-classes" that may have everything anyone could ever want but
more than most will ever use.

In other words, if a class changes in the future so that it now uses
unmanaged resources, then a new version of the assembly would be warranted.
This new version would not automatically be used by apps. that were using
the older version so, there would not be a problem. Applications that use
this new version, would then call Dispose.
 
M

Matt Osborne

I agree. From all that I have read, the only time that you should implement
IDisposable is if you are using unmannaged resources. Since there is as of
yet no data access API that is 100% managed (and there will not likely ever
be) it is important to dispose all objects that implement IDisposable. We
have had problems in the past with memory leaks that were not resolved until
we started calling Dispose.

The only caution that I offer with Dispose is that once its called, there is
no going back. Make sure that there are not other objects refrencing the
disposed object as they could cause exceptions if methods or properties are
called after Dispose is called.

Matt Osborne

Miha Markic said:
How do you know if the class is holding unmanaged resources?
You should call Dispose on every instance to relase resources asap.
Plus, you don't know what the future changes might be.
So, call Dispose on anything that implements IDisposable asap.

--
Miha Markic [MVP C#] - RightHand .NET consulting & development
SLODUG - Slovene Developer Users Group
www.rthand.com

Scott M. said:
You really don't need to bother disposing a DataSet (or any other .NET
object for that matter) unless the object is holding on to unmanaged
resources that need to be manually cleaned up when you are done using the
object. This is the whole point of the Garbage Collector.
 
S

Scott M.

You've made 2 contradictory statements here:
---------
"I agree. From all that I have read, the only time that you should
implement IDisposable is if you are using unmanaged resources. "

....and...

"Since there is as of yet no data access API that is 100% managed (and there
will not likely ever be) it is important to dispose all objects that
implement IDisposable."
----------

I would agree that when we are talking about data access classes, calling
Dispose is generally wise. But, not all classes that expose a Dispose
method are data access classes (in fact, the vast majority aren't) and for
those there may be no need at all in calling Dispose.



Matt Osborne said:
Since there is as of
yet no data access API that is 100% managed (and there will not likely
ever
be) it is important to dispose all objects that implement IDisposable. We
have had problems in the past with memory leaks that were not resolved
until
we started calling Dispose.

The only caution that I offer with Dispose is that once its called, there
is
no going back. Make sure that there are not other objects refrencing the
disposed object as they could cause exceptions if methods or properties
are
called after Dispose is called.

Matt Osborne

Miha Markic said:
How do you know if the class is holding unmanaged resources?
You should call Dispose on every instance to relase resources asap.
Plus, you don't know what the future changes might be.
So, call Dispose on anything that implements IDisposable asap.

--
Miha Markic [MVP C#] - RightHand .NET consulting & development
SLODUG - Slovene Developer Users Group
www.rthand.com

Scott M. said:
You really don't need to bother disposing a DataSet (or any other .NET
object for that matter) unless the object is holding on to unmanaged
resources that need to be manually cleaned up when you are done using the
object. This is the whole point of the Garbage Collector.


Hi,

Once a dataset is populated from DataAdapter, I want to release the
memory acquired by dataSet object. So I call oDataSet.Dispose(). But
it doesnot disposes the internal objects like Datatable/dataColumn.

Should I have to call Dispose() method for these internal objects
explicitely? OR DataSet.Dispose() takes care to clear the internal
objects?

Thanx,
Atul
 
M

Miha Markic [MVP C#]

Scott M. said:
It's not difficult to know if an object is holding unmanaged resources
since the user of the object will be the one who "connected" the object to
the resource in the first place.

The whole point of garbage collection is to take the process of managing
of memory away from the developer. Dispose is simply a method call that
*some* (not all) classes have that is a good place to do clean up work
with unmanaged resources. Calling Dispose on anything that implements
IDisposable will result in a lot of unnecessary method calls. Your advice
is cautionary, but not realistic, efficient or necessary.

Hm, don't you think that there *might* be a reason that a class implements
IDisposable?
 
S

Stephen B. Hahn

DataSet is not a Data Access object, it is a disconnected object containing
various data related collections. DataAdapter, Command and Connection are Data
Access objects. DataSet does not implement IDisposable directly. It inherits
it from MarshalByValueComponent. If you use Reflector you can see that it's
Dispose method does not release unmanaged resources or call. Thus I'd say call
dispose on a DataSet object is a waste of cycles. Setting the reference to Null
or letting it go out of scope is not.

Here's Reflectors disassemble of the code, Dispose() calls Dispose(true):

protected virtual void Dispose(bool disposing)
{
if (disposing)
{
lock (this)
{
if ((this.site != null) && (this.site.Container != null))
{
this.site.Container.Remove(this);
}
if (this.events != null)
{
EventHandler handler1 = (EventHandler)
this.events[MarshalByValueComponent.EventDisposed];
if (handler1 != null)
{
handler1(this, EventArgs.Empty);
}
}
}
}
}



Scott M. said:
You've made 2 contradictory statements here:
---------
"I agree. From all that I have read, the only time that you should
implement IDisposable is if you are using unmanaged resources. "

...and...

"Since there is as of yet no data access API that is 100% managed (and there
will not likely ever be) it is important to dispose all objects that
implement IDisposable."
----------

I would agree that when we are talking about data access classes, calling
Dispose is generally wise. But, not all classes that expose a Dispose
method are data access classes (in fact, the vast majority aren't) and for
those there may be no need at all in calling Dispose.

Matt Osborne said:
Since there is as of
yet no data access API that is 100% managed (and there will not likely
ever
be) it is important to dispose all objects that implement IDisposable. We
have had problems in the past with memory leaks that were not resolved
until
we started calling Dispose.

The only caution that I offer with Dispose is that once its called, there
is
no going back. Make sure that there are not other objects refrencing the
disposed object as they could cause exceptions if methods or properties
are
called after Dispose is called.

Matt Osborne

Miha Markic said:
How do you know if the class is holding unmanaged resources?
You should call Dispose on every instance to relase resources asap.
Plus, you don't know what the future changes might be.
So, call Dispose on anything that implements IDisposable asap.

--
Miha Markic [MVP C#] - RightHand .NET consulting & development
SLODUG - Slovene Developer Users Group
www.rthand.com

You really don't need to bother disposing a DataSet (or any other .NET
object for that matter) unless the object is holding on to unmanaged
resources that need to be manually cleaned up when you are done using the
object. This is the whole point of the Garbage Collector.


Hi,

Once a dataset is populated from DataAdapter, I want to release the
memory acquired by dataSet object. So I call oDataSet.Dispose(). But
it doesnot disposes the internal objects like Datatable/dataColumn.

Should I have to call Dispose() method for these internal objects
explicitely? OR DataSet.Dispose() takes care to clear the internal
objects?

Thanx,
Atul
 
J

Jon Skeet [C# MVP]

Hm, don't you think that there *might* be a reason that a class implements
IDisposable?

Unfortunately, DataSet derives from MarshalByValueComponent, which
brings along IDisposable baggage. I'd call Dispose on it if I were
remoting it, or marshalling it across AppDomain boundaries, but I
wouldn't bother otherwise.

In general though, I agree with you - unless I've taken a close look at
why something implements IDisposable and decided that it's a red
herring in the case I'm using, I call Dispose on it.
 
M

Miha Markic [MVP C#]

Hi Jon,

Jon Skeet said:
Unfortunately, DataSet derives from MarshalByValueComponent, which
brings along IDisposable baggage. I'd call Dispose on it if I were
remoting it, or marshalling it across AppDomain boundaries, but I
wouldn't bother otherwise.

In general though, I agree with you - unless I've taken a close look at
why something implements IDisposable and decided that it's a red
herring in the case I'm using, I call Dispose on it.

What if the implementation changes from 1.0 -> 1.1? Or 1.x->2.0?
Will you go through all classes and recheck the Dispose implementation?
Don't take me wrong as I also didn't Dispose everything blindly.
However, it seems more and more a good choice to Dispose everything so I try
to be on the safe side.

Guys, read what Angel has to say on the issue:
http://www.google.com/groups?hl=en&...spose&safe=images&as_uauthors=angel&lr=&hl=en
 
J

Jon Skeet [C# MVP]

What if the implementation changes from 1.0 -> 1.1? Or 1.x->2.0?
Will you go through all classes and recheck the Dispose implementation?
Don't take me wrong as I also didn't Dispose everything blindly.
However, it seems more and more a good choice to Dispose everything so I try
to be on the safe side.

But DataSet (and DataTable, DataRow etc) are always going to be managed
in-memory data structures, I believe - if that changes, that's going to
be the major kind of change which should be shouted from the rooftops,
as it'll have bigger connotations than just whether or not Dispose
should be called. DataSet is a fundamentally wholly-managed type in a
way that SqlCommand isn't. I wouldn't be surprised if in the future,
SqlCommand ended up with unmanaged resources somewhere (like
SqlCeCommand does), because it's got at least *something* to do with a
world outside the CLR, namely the SQL server. DataSet, however, unless
it's being remoted or marshalled, should be wholly within the normal
realm of the garbage collector.
Guys, read what Angel has to say on the issue:
http://www.google.com/groups?hl=en&lr=&c2coff=1&threadm=OBUX6gRjDHA.2
640%40TK2MSFTNGP10.phx.gbl&rnum=2&prev=/groups%3Fas_q%3Ddispose%26safe
%3Dimages%26as_uauthors%3Dangel%26lr%3D%26hl%3Den

Interesting and IMO odd that he recommends calling Close on
SqlConnection as well as Dispose, given that he says it calls Close if
necessary anyway. The only benefit of calling Close over calling
Dispose is that you can then re-open the connection if you want, as far
as I can see.
 
M

Miha Markic [MVP C#]

But DataSet (and DataTable, DataRow etc) are always going to be managed
in-memory data structures, I believe - if that changes, that's going to
be the major kind of change which should be shouted from the rooftops,
as it'll have bigger connotations than just whether or not Dispose
should be called. DataSet is a fundamentally wholly-managed type in a
way that SqlCommand isn't. I wouldn't be surprised if in the future,
SqlCommand ended up with unmanaged resources somewhere (like
SqlCeCommand does), because it's got at least *something* to do with a
world outside the CLR, namely the SQL server. DataSet, however, unless
it's being remoted or marshalled, should be wholly within the normal
realm of the garbage collector.

These are only speculations (which are probably good ones :) ) as nobody
can foresee the future.
If some kind of change occur and even if it is shouted from the rooftops :)
you will have great deal of work to go through all your applications and
re-check it. But ok, this is not very much probable.
Plus, Dispose on DataSet will remove it from container it it is hosted,
otherwise it will live with container.

Interesting and IMO odd that he recommends calling Close on
SqlConnection as well as Dispose, given that he says it calls Close if
necessary anyway. The only benefit of calling Close over calling
Dispose is that you can then re-open the connection if you want, as far
as I can see.

Well, Dispose on sqlconnection object has not much effect - it just removes
the component from container if it is hosted and tries to close the
connection if its status is ConnectionState.Open.
I can see that there might be a problem since connection state is a flag and
dispose checks directly against .Open (not doing OR at all).
Thus, is better to invoke Close() explictly.
 
J

Jon Skeet [C# MVP]

These are only speculations (which are probably good ones :) ) as nobody
can foresee the future.
If some kind of change occur and even if it is shouted from the rooftops :)
you will have great deal of work to go through all your applications and
re-check it. But ok, this is not very much probable.

Indeed - just as unlikely as a type which didn't implement IDisposable
before later implementing it, to my mind.
Plus, Dispose on DataSet will remove it from container it it is hosted,
otherwise it will live with container.

Yes, in situations where I'm using it in a container and want the
container to outlive it (which is rare, IMO - I rarely use containers
anyway, to be honest) I'd call Dispose.
Well, Dispose on sqlconnection object has not much effect - it just removes
the component from container if it is hosted and tries to close the
connection if its status is ConnectionState.Open.

Closing the connection seems a pretty significant effect to me!
I can see that there might be a problem since connection state is a flag and
dispose checks directly against .Open (not doing OR at all).
Thus, is better to invoke Close() explictly.

Why? Close only does anything if the flag is Open too.

I'd be amazed if you could produce some sample code which clearly
demonstrated Close doing more than Dispose. (The difference in terms of
reopening is a separate issue.)
 
M

Miha Markic [MVP C#]

Closing the connection seems a pretty significant effect to me!

Oh, i expressed myself badly - it has not much effect besides closing
connection should be better.
Actaully, it does another step that Close doesn't. See below.
Why? Close only does anything if the flag is Open too.

Ooops. Yes, I missed that part - actually I didn't look because I've assumed
that it does something more then Dispose does.
I see that Dispose just calls Close.
However, there is one more thing that Dispose does - it resets the
connection string.
 
C

Cor Ligthert

Miha,

This what you "now" write is in my opinion all in contradiction Angel has
written in this newsgroup and I don't have the idea that he has the last
months changed that.

http://tinyurl.com/5lucm

That the documentation tells that it is only removing as extra the
connectionstring is something we know probably all.

Cor
 
C

Cor Ligthert

Miha,

Before you misunderstand me, about the dataset I was yesterday busy writing
a same answer as Scott and Alvin when I saw that they had done it. Therefore
I did not see a reason anymore for that, than it can looks if we are
atacking you and that is something I surely do not want to do.

:)

Cor

"Miha Markic [MVP C#]"
 

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