Need More ADO Suggestions

  • Thread starter Thread starter Jonathan Wood
  • Start date Start date
Jonathan Wood said:
Scott,


GC will optimize the heap, which prolongs running out of memory as long as
possible. I'm sorry, but you are mistaken if you think GC can prevent
running out of memory.

GC does more than optimize the heap, it "manages" the heap and makes
decisions about "when" and "if" objects need to be destroyed. To say that
the GC can't prevent us from running out of memory is incorrect. It most
certainly can and does.
I just got through describing that the very example you gave shows that we
not only need to know something about whether or not the class maintains
resources that must be cleaned up, but now we also need to know about
which classes might clean up other classes. I don't know how you define
encapsulation but to me it's about only needing to understand a class's
interface to use it, and not anything about it's implementation. That's
more than one clear example of how the lack of DF is a step in the other
direction.

And, I've said that we learn what we need to know from the interfaces of the
objects involved. We do not need to know how they do what they do. You
most certainly *can* call dispose on your Command object, but in the
scenario you've shown, it is unneccessary. I do not believe that having a
basic understanding of the nuances of a class so that I can use them more
effectively breaks encapsulation.
Again, I understand you may never agree to this but I've been doing this
long enough to understand the benefits of OOP and encapsulation. And,
here, learning this stuff is harder because I am not gaining all the
traditional benefits of OOP and encapsulation.

It's just my opinion. YMMV.

Ah, but I've been doing this long enough (from this side of the fence) to
understand the benefits of OOP in a managed environment. As a matter of
fact, I am a technology trainer and have been teaching .NET since its
inception. I have encountered many folks, just like yourself (comming to
..NET from a lower-level programming language like C/C++) and, over and over
seen that, for these folks, the switch to this managed framework can be
difficult due to the additional burdens the C/C++ environment places on
developers, but how used to it they get and how they are reluctant to give
it up as they move into .NET. There really much, in the way of OO benefits,
that you are losing here.

What if I had just told you to call dispose on any object that has such a
method and that this would be sufficient to cause the object to clean up
appropriately? That would put your whole argument about encapsulation to
rest, wouldn't it? Because if you choose to code by that rule, it will not
cause you *any* troubles in any situation you encounter, ever. You can code
this way, feel good about encapsulation and not feel that you've lost
anything. But, it just happens that a command object has a dispose method
because it inherits from the component class (which exposes such a method)
and that Microsoft puts a dispose method on the component class for the
benefit of the many subclasses in the framework that do *need* this
functionality. It just turns out that the command object doesn't. Now, you
know that encapsulation says the we do not *need* to know about an object's
implementation in order to use it and I still maintain that is true here. I
could have never mentioned anything about Dispose and your code would
function exactly as it needs to. But, you can't tell me that *if* I happen
to know something about an object's implementation, that I wouldn't be able
to write code for it in a more optmized way. That is not what encapsulation
says. I still maintain that we have full encapsulation here.

I really think that you should do a little more research on the GC, which
will show you that it does, in fact, protect us from memory leaks and
outages, which makes much of what you have been inquiring about (where to
use Try...Catch and creating "bullet-proof" non-crashable code), not an
issue in all but extreme coding scenarios or poorly designed hardware
architectures. There's no such thing as "bullet-proof" or "uncrashable"
code in any lanaguge. No, I can't make you that guarantee. But I can tell
you that for very nearly 100% of situations, running out of memory due to
simply instantiating an object won't or can't cause us to run out of memory.
In the extremely rare scenarios where it might, we'd most likely to
attribute the cause to either unmanaged resources not being properly used or
very poorly written managed code. But, hey, you can write bad code in any
language.

As for your original concern about persisting a copy of the data in a
DataSet, again I'll refer you to more research on the GC, the DataSet and
DataTable classes, and the overhead of keeping an active database "hook"
longer than is really needed.

-Scott
 
Scott,
GC does more than optimize the heap, it "manages" the heap and makes
decisions about "when" and "if" objects need to be destroyed.

That process of destroying objects as well as rearranging memory is what I
meant by optimize.
To say that the GC can't prevent us from running out of memory is
incorrect. It most certainly can and does.

It may be that the chances you'll run out of memory are exceedingly low, but
to suggest GC prevents us from doing so makes no sense. If you still
disagree, have a look at what MS says about the new operator allocating
memory in C#:

"If the new operator fails to allocate memory, it throws the exception
OutOfMemoryException."
http://msdn2.microsoft.com/en-us/library/51y09td4(VS.71).aspx

Obviously, there is only so much memory. How can GC prevent us from running
out?
scenario you've shown, it is unneccessary. I do not believe that having a
basic understanding of the nuances of a class so that I can use them more
effectively breaks encapsulation.

Then we apparently have different working definitons of "encapsulation."
Ah, but I've been doing this long enough (from this side of the fence) to
understand the benefits of OOP in a managed environment.

The principles and benefits of OOP have not changed just because OOP has
been implemented in a managed environment.
What if I had just told you to call dispose on any object that has such a
method and that this would be sufficient to cause the object to clean up
appropriately? That would put your whole argument about encapsulation to
rest, wouldn't it? Because if you choose to code by that rule, it will not
cause you *any* troubles in any situation you encounter, ever.

It could affect performance and, no matter how easy the IDE makes it to
determine whether or not a class implements Dispose, it still must be known
and so it supports my position.
I really think that you should do a little more research on the GC

Perhaps you can point out one aspect of GC that I have demonstrated I do not
understand. I have discussed these issues at Microsoft face-to-face with
..NET developers before .NET was initially released.
which will show you that it does, in fact, protect us from memory leaks

Did you interpret any of my comments to imply that GC does not eliminate
memory leaks?
which makes much of what you have been inquiring about (where to use
Try...Catch and creating "bullet-proof" non-crashable code), not an issue
in all but extreme coding scenarios or poorly designed hardware
architectures.

I'm sorry, but I'm just blown away by some of the things you are saying. The
fact is that I wish I had a dollar for every Website I've played around with
that threw up the familiar ASP.NET error page. If you are happy with that,
then it is not an issue. Otherwise, it should be an issue.
As for your original concern about persisting a copy of the data in a
DataSet, again I'll refer you to more research on the GC, the DataSet and
DataTable classes, and the overhead of keeping an active database "hook"
longer than is really needed.

That issue has already been resolved to my satisfaction. The issue is a bit
more complex about when to use a DataReader and when to use a DataSet, but
the issue about closing the connection made perfect sense to me, I
understood it, and I moved on.
 
Jonathan Wood said:
Scott,


That process of destroying objects as well as rearranging memory is what I
meant by optimize.


It may be that the chances you'll run out of memory are exceedingly low,
but to suggest GC prevents us from doing so makes no sense. If you still
disagree, have a look at what MS says about the new operator allocating
memory in C#:

"If the new operator fails to allocate memory, it throws the exception
OutOfMemoryException."
http://msdn2.microsoft.com/en-us/library/51y09td4(VS.71).aspx

Obviously, there is only so much memory. How can GC prevent us from
running out?

I've said that it is *possible* for applications to run out of memory, but
you've snipped those comments in your replies. I've said that the causes for
running out of memory are going to be poor hardware architecture, unmanaged
resource allocation (which is outside of the GC's control) and/or poor
programming. No one can ever make you a rock-solid guarantee that these
things won't happen, but if we just talk about what the GC has control over
(managed code) and we talk about that managed code written by someone with a
basic understanding of object memory allocation, we do find that the GC
protects us from running out of memory by cleaning the heap when memory
resources begin to get low. If your response to that statement is along the
lines of "What if there are not enough resources for the GC to release and
so we still run out of memory?", then my response is that we are working in
a poorly architected hardware environment and this is not a programming
issue at all.
Then we apparently have different working definitons of "encapsulation."

I guess we do.
The principles and benefits of OOP have not changed just because OOP has
been implemented in a managed environment.


It could affect performance

Not calling it could affect performance. It's there because in most cases
it performs important work that prevents problems from occuring.
and, no matter how easy the IDE makes it to determine whether or not a
class implements Dispose, it still must be known and so it supports my
position.

Let me ask you something...How did you find out that a Command object has an
ExecuteReader method? Didn't you have to somehow "know" that there was a
method that wouuld invoke your command's commandText and return an object
that you could use to iterate over the results of that commandText? I just
don't understand your assertion that to investigate the members of a class
to determine what the available members are and get a basic understanding of
what those members do is counter to any OOP principle. I'll say it again,
encapsulation does not mean we shouldn't have to look at an object's
interface and try to determine what the variouse interface members do, it
means that we shouldn't have to know or care *how* those members do what
they do. Without becomming knowledgeable about the existence of the
members, you couldn't write a line of code.
Perhaps you can point out one aspect of GC that I have demonstrated I do
not understand.

How about two?

1. You said that the GC cannot protect us from running out of memory, which
is incorrect. I have explained that what I mean by this is not that the GC
will protect us from *all* out of memory exceptions (poor hardware design,
poor coding techniques, unmanged resource allocation outside of the GC's
control), but for what the GC does have control over, it can and does
prevent us from running out of memory. Even though I've said this a few
times now, you still seem to disagree with this, which is just incorrect.

2. You also questioned me when I said that the GC determines *if* objects
will be released, indicating that you believed that all objects will be
removed at some point, which may not be the case. In fact, and you may
already know this, the GC doesn't finalize all "collectable" objects when it
is cleaning the heap. Objejcts are organized into "generations" and
promoted upon each collect until they eventually reach a point where they
will be collected in the next collection cycle - - but, as I've indicated,
in a system that has a lot of available resources, there may not be a need
for the GC to collect, resulting in objects that are elligible for
collection, but not collected.
I have discussed these issues at Microsoft face-to-face with .NET
developers before .NET was initially released.

I don't see how that makes your inaccurate statements about the GC, the
memory implications of using DataReaders and DataSets, and the potential for
creating instances causing us to run out of memory any less incorrect.
Did you interpret any of my comments to imply that GC does not eliminate
memory leaks?

No, I simply added this as an additional benefit of what the GC does - - I
believe there was more to my statement above, but you snipped it.
I'm sorry, but I'm just blown away by some of the things you are saying.
The fact is that I wish I had a dollar for every Website I've played
around with that threw up the familiar ASP.NET error page. If you are
happy with that, then it is not an issue. Otherwise, it should be an
issue.

I don't know what statements I've made that you are blown away by, but your
statement above is too general for me to give a specific reply to. I will
say that, you've admitted that you are new to much of this .NET stuff and
I've told you that I've worked with and taught it for nearly 7 years now.
You've also heard from "Cowboy" a.k.a. Greg (who has written a book on ADO
..NET) on this. Perhaps there's something we know on these issues that you
don't?

You'll also have to be more specfic as to what error page you are referring
to. Because, as I've said, you can write poor code in any language and if
you are seeing ASP .NET error pages on production web sites, then the
developer's of those sites didn't even know how to disable exception error
messages from displaying to the general public in web.config, which tells me
that you are using examples of sites that use bad code or are written by
poorly skilled developers to start with. I mean give me a language and I
can crash the system it runs on pretty easily with a simple loop.
That issue has already been resolved to my satisfaction. The issue is a
bit more complex about when to use a DataReader and when to use a DataSet,
but the issue about closing the connection made perfect sense to me, I
understood it, and I moved on.

Well, by your comment here, it makes me wonder how much you really do
understand all of this, because when to use a DataReader vs. when to use a
DataSet is actually not that complex of a decision. Understanding the GC's
role and how well it fufills that role is key to understanding why this.

Anyway, I do wish you good luck in your .NET endeavors.

-Scott
 
Scott,

I nowhere have read (as you wrote it, then excuse, I did not read
everything) in your in my idea very correct replies that you can run out of
resources. Probably the main reason that de dispose method was included in
the compenents to be *able* to clean them up yourself, like you wrote.

(And which it is advised everywhere to use where very much resources are
used by instance with drawing stuff, however not with AdoNet).

Cor
 
Back
Top