I've been writing a C# app that is, among other things, a front-end to a few PostgreSQL databases. I'm using System.Data.Odbc and the using( OdbcConnection cn = new ...){ ... } syntax which properly automatically closes the connection.
I know my question sounds like something a lazy, careless developer might ask, but that's not really it. To be sure I'm the first to admit that *I* introduced a bug that resulted from poor attention to detail and fixed it. But it got me to thinking about how the using( OdbcConnection cn = new ...) { ... } is implemented and there is something about it I don't like that reminds me of the (imo) extreme care one must take doing XL automation coding so as to avoid Excel continuing to run in the background after your automation app is closed. The bug I introduced is analogous, imo, to the issues with XL automation.
Inside the using( OdbcConnection cn ...) fragment, I open a cursor and then use an OdbcDataReader object to iterate through the cursor. In one case, I didn't explicitly close the reader. What happens when you do that is that the containing connection is indeed closed and your object variable is set to null as expected, but the database connection remains open on the database server. This leads me to my issue with how using ( OdbcConnection cn = new ... ){} is implemented. If there are dependent objects on the OdbcConnection that are still instantiated and open when the "}" is encountered, shouldn't those dependent objects be closed and set to null before the connection object is closed and set to null?
From my POV, I don't think I'm being pedantic (or lazy, careless, stupid, etc.), it just seems to me that if object variables are declared in a block dependent upon another object that defines that block, before the container object is closed and goes out of scope, dependent objects *should* close (a sort of "Delete Cascade ..." if you will). I've already conceded it was sloppy of me not to explicitly Close() my reader object, but because I'd done that, Idle connections were left open on the database server and that happened silently.
In short, I don't think writing the code below...
1 using( OdbcConnection cn = new OdbcConnection(connString)
2 {
3 cn.Open();
4
5 using( OdbcCommand cmd = new OdbcCommand( SqlQueryString, cn )
6 {
7 OdbcDataReader reader = cmd.ExecuteReader();
8
9 while( reader.Read() )
10 {
11 --- Do something with the data
12 }
13
14 }
15
16 }
Should leave you with open connections on a database server that you cannot close because you no longer have a way to reference those connections simply because you did not include the code "reader.Close()" on line 13. Is it sloppy not to include that? Of course. But it is no LESS sloppy imo to close the OdbcCommand Object and the OdbcConnection Object and free them without closing and freeing the OdbcDataReader object.
Anybody have an opinion that?
I know my question sounds like something a lazy, careless developer might ask, but that's not really it. To be sure I'm the first to admit that *I* introduced a bug that resulted from poor attention to detail and fixed it. But it got me to thinking about how the using( OdbcConnection cn = new ...) { ... } is implemented and there is something about it I don't like that reminds me of the (imo) extreme care one must take doing XL automation coding so as to avoid Excel continuing to run in the background after your automation app is closed. The bug I introduced is analogous, imo, to the issues with XL automation.
Inside the using( OdbcConnection cn ...) fragment, I open a cursor and then use an OdbcDataReader object to iterate through the cursor. In one case, I didn't explicitly close the reader. What happens when you do that is that the containing connection is indeed closed and your object variable is set to null as expected, but the database connection remains open on the database server. This leads me to my issue with how using ( OdbcConnection cn = new ... ){} is implemented. If there are dependent objects on the OdbcConnection that are still instantiated and open when the "}" is encountered, shouldn't those dependent objects be closed and set to null before the connection object is closed and set to null?
From my POV, I don't think I'm being pedantic (or lazy, careless, stupid, etc.), it just seems to me that if object variables are declared in a block dependent upon another object that defines that block, before the container object is closed and goes out of scope, dependent objects *should* close (a sort of "Delete Cascade ..." if you will). I've already conceded it was sloppy of me not to explicitly Close() my reader object, but because I'd done that, Idle connections were left open on the database server and that happened silently.
In short, I don't think writing the code below...
1 using( OdbcConnection cn = new OdbcConnection(connString)
2 {
3 cn.Open();
4
5 using( OdbcCommand cmd = new OdbcCommand( SqlQueryString, cn )
6 {
7 OdbcDataReader reader = cmd.ExecuteReader();
8
9 while( reader.Read() )
10 {
11 --- Do something with the data
12 }
13
14 }
15
16 }
Should leave you with open connections on a database server that you cannot close because you no longer have a way to reference those connections simply because you did not include the code "reader.Close()" on line 13. Is it sloppy not to include that? Of course. But it is no LESS sloppy imo to close the OdbcCommand Object and the OdbcConnection Object and free them without closing and freeing the OdbcDataReader object.
Anybody have an opinion that?