[dba-VB] c# so FINALLY ?

Shamil Salakhetdinov shamil at smsconsulting.spb.ru
Sat Jul 24 11:33:53 CDT 2010


Hi John --

Thank you for your questions.

<<<
> Dispose does all the clean-up for SqlCommand object instance...
Is my code above correct then?
>>>
Yes, it's more than correct IMO :) - I must say I almost never use that much
clean-up coding in my .NET development:

- I do never clean-up SqlCommand and SqlDataReader explicitly;
- I do never close/clean-up SqlConnection;
- I do use 

try {
using (SqlConnection cnn = new SqlConnection(connectionString)
{
	// SqlCommand and SqlDataReader etc. are in
}
} 
catch (SqlException ex) 
{
  // log exception
  throw ex; 	   	
}
catch (Exception ex) 
{
  // log exception
  throw ex; 	   	
}

Yes, I do use 'throw ex' not just 'throw' - and that my "approach" could be
not so good
(http://geekswithblogs.net/sdorman/archive/2007/08/20/Difference-between-quo
tthrowquot-and-quotthrow-exquot-in-.NET.aspx ) but I do use it for several
years in db intensive multi-user web apps - and it works well - no "memory
leakage" - and I must say I have used my logging just a few times and it was
informative enough to find and fix the bugs...

"Excessive clean-up" is not needed in .NET as CLR's garbage collector does
do good job for the code as above...

<<<<<<
If I log in the catch block do I really want to then throw 
the error?  What is the calling procedure going to do with that?
It seems logical to me to do the logging in the catch block 
and then NOT throw the error, but rather simply return 
a boolean false saying that the process failed.  
The calling procedure can then use 
the boolean to decide what to do.  My understanding is that 
if I throw the error up to the caller 
then it ends up in its catch block, which may throw the error etc.
I am good with handling the error close to the source but it just seems that
implies NOT throwing 
the error on up.
>>>>>>
John, IMO there is no generic/common answer to your question - it depends on
your app what to do with handled exception - "log and buble it up" or "log
and suppress it" returning boolean failure code to the caller method: 

- logging and using Boolean is what is called "defensive" programming AFAIU
- and it's "heavy good old professional style";
- logging and throwing and exception up to the higest level caller is what
is called "modern lightweight programming style" - in my opinion :) - and
it's the most recommended nowadays AFAIS...

Of course in the latter case of "modern lightweight programming style" there
should be something(/some code) on the upper call stack levels to take care
of the exception (to make some more logging and) to:

- continue application execution gracefully;
- quit the application...

<<<
And of course I need a reliable logger so that I can go see any errors.
>>>
I do not use any besides some custom simple coding I outlined in this
thread:

- I just log into a simple text file;
- I log into MS SQL, if that fails, log into text file, if that fails log
into MS Windows application log.

You can plan to use some existing logging frameworks but for the time beeing
just write simple custom wrapper class, and then you can add advanced
logging later...

<<<
And I have to make a living while I am learning, 
>>>
Yes, that's our destiny - the same story here, moreever...

<<<
and I am trying to teach a young fellow that works for me 
what little I know as well.
>>>
If this young fellow is from a good IT college then they can teach you a lot
(myself included) - I mean they usually know well all the modern
approaches/methods of application programming - yes, more in theory than in
practice but they often have a good overview we (seasoned developers) might
lack because of the lack of time to study the theory - "fighting" everyday
for living - just talk to the "kid programmer" - and you'll together will
find your "proper" way of programming together...

I suppose that for your case there are two proven sources:

- ASP.NET 2.0 Website Programming: Problem - Design - Solution (Programmer
to Programmer)
(http://www.amazon.com/ASP-NET-2-0-Website-Programming-Programmer/dp/0764584
642) - it has real life sample web site/code solution with multi-layer
"framework" - I did quote "framework" because it has just a few classes -
you can "grab and use them" (sources are available free on WROX site)...

- CSLA .NET for Windows (http://www.lhotka.net/cslanet/ ) - it's a huge
framework - and I personally do not use it - I'd recommend to just get its
sources (they are free) and to investigate the part of code belonging to the
DataAccessLayer (DAL) - "suppress your temptation" (:)) to use this
framework immediately - it would be very time consuming to learn it in
details...

I also suppose that nowadays combination of ADO.NET Entity Framework 4.0 +
custom SPs mapping to your ADO.NET EF DataModel would be "what doctor
ordered" but again it could take a lot of time to learn that "super modern"
stuff - you can use simpler and time proven approaches referred above while
learning/testing the latter (ADO.NET EF + custom SPs) in your spare time (if
any)....

Thank you.

-- Shamil

P.S: Disclaimer: All the above my opinions are coming from my own everyday
.NET development experience, and are also gathered on Web, including
Access-D/dba-VB and from technical books - they can be my own
"misinterpretation or real world" sometimes - but they work well for me and
for my customers :)

-----Original Message-----
From: dba-vb-bounces at databaseadvisors.com
[mailto:dba-vb-bounces at databaseadvisors.com] On Behalf Of jwcolby
Sent: Saturday, July 24, 2010 1:26 PM
To: Discussion concerning Visual Basic and related programming issues.
Subject: Re: [dba-VB] c# so FINALLY ?

Shamil,

Thanks for your reply.  C#, .Net and Visual Studio are very complex and I
have so much to learn. 
And I have to make a living while I am learning, and I am trying to teach a
young fellow that works 
for me what little I know as well.

I need more information from you.

I have two specific things I am trying to implement and make sure that I
"cleanup" correctly.  The 
first is that I have a ton of places in my code where I am using SQL Server
records for table driven 
processes.  As such I need to:

1) Work with data readers, looping through records.
2) Work with command objects doing .ExecuteNonQuery() to perform updates on
flags.

In both these scenarios I want to make sure that I open the connection, open
the command object, do 
whatever the command object is going to do, close the connection, and
cleanup the command object. 
And I want (am trying) to do this in a single place so that I get consistent
object handling / 
cleanup. So, for example I use a static method of a class:

         public static bool ExecNonQuery(string strCnn, string strSQL)
         {
             SqlConnection mCnn = null;
             SqlCommand myCommand = null;
             try
             {
                 mCnn = new SqlConnection(strCnn);
                 mCnn.Open();
                 myCommand = new SqlCommand(strSQL, mCnn);
                 myCommand.ExecuteNonQuery();
             }
             catch (SqlException)
             {
                 throw;
             }
             catch (Exception)
             {
                 throw;
             }
             finally
             {
                 if (myCommand != null)
                 {
                     myCommand.Dispose();
                     myCommand = null;
                 }
                 if (mCnn != null)
                 {
                     mCnn.Close();
                 }
             }
             return true;
         }

 > Dispose does all the clean-up for SqlCommand object instance...

Is my code above correct then?

 > It doesn't make sense to have any SUCCESS/FAILURE return values from this
method as it has throw 
calls inside of catch blocks

OK.  So if the .ExecuteNonQuery fails to work, the throw happens but...

 > Again follow KISS-principle: - log exceptions as close as possible to the
point where they appeared;

If I log in the catch block do I really want to then throw the error?  What
is the calling procedure 
going to do with that?

It seems logical to me to do the logging in the catch block and then NOT
throw the error, but rather 
simply return a boolean false saying that the process failed.  The calling
procedure can then use 
the boolean to decide what to do.  My understanding is that if I throw the
error up to the caller 
then it ends up in its catch block, which may throw the error etc.

I am good with handling the error close to the source but it just seems that
implies NOT throwing 
the error on up.

And of course I need a reliable logger so that I can go see any errors.

John W. Colby
www.ColbyConsulting.com






More information about the dba-VB mailing list