Reputation: 44
While refactoring code I stumbled upon some stacked using statements (I'm talking about 10 to 15-ish).
using(X x=new X())
using(Y y=new Y())
using(Z z=new Z())
using(...)
{
List<X> listX= x.GetParameterListByID(pID);
List<Y> listY=y.GetParameterListByID(pID);
...
...
//other (business) calls/code, like 20-30 lines, that don't need the using instances
}
Class example would be something like
public class X : IDisposable{
public List<XParameterInfo> GetParameterListByID(int? pID){
const string query="SELECT name,value FROM parameters WHERE id=@ID";
//query code here
return queryResult;
}
}
And the first thing I thought of was, knowing that a using
is basicly a try{} finally{ x.Dispose(); }
, that the using connections would be kept open/active untill the code within the using block is finished while it is only needed to fill one list.
The above is what I assume, correct me if I'm wrong. Considering what I said is correct, would it be better (performance, but mostly good practice-wise) to write something like
List<X> listX;
List<Y> listY;
List<Z> listZ;
...
//for the example here I wrote out 3 but let's talk 10 or more
using(X x=new X())
{
listX=x.GetParameterListByID(pID);
}
using(Y y=new Y())
{
listY=y.GetParameterListByID(pID);
}
using(Z z=new Z())
{
listZ=z.GetParameterListByID(pID);
}
...
// other calls but now outside the using statements
or is it negligible, other than the fact that stacked using
statements take away the nested code look?
Upvotes: 2
Views: 164
Reputation: 5877
In addition to what Tim said, many DB drivers use "Connection Pooling" to increase the performance of connections, by reusing old ones. So when Dispose
is called upon connections, they don't really close (except after certain conditions are met), but they are kept idle for subsequent calls.
https://learn.microsoft.com/en-us/dotnet/framework/data/adonet/connection-pooling
Upvotes: 2
Reputation: 11
Why don't you use 1 connection for all the queries?
I think this would be a more elegant solution.
void Main()
{
List<X> listX;
List<Y> listY;
List<Z> listZ;
using(SqlConnection conn = new SqlConnection())
{
conn.Open();
listX=new X().GetParameterListByID(conn, pID);
listY=new Y().GetParameterListByID(conn, pID);
listZ=new Z().GetParameterListByID(conn, pID);
}
}
Upvotes: 1
Reputation: 460238
would it be better (performance wise)
that depends on the types that are used in the using. You can't make a general statement.
Performance is not the only factor, open resources can block other processes or cause memory issues. But on the other side readability is increased with the more compact first version. So you have to decide if there is an issue at all. If not, why bother? Then chose the best readable and maintainable code.
But you could refactor your code, use a method to encapsulate the usings:
// in class X:
public static List<X> GetParameterListByID(int pID)
{
using(X x = new X())
{
return x.GetParameterListByID(pID);
}
}
// and same in other classes
Now the code has no usings:
List<X> listX = X.GetParameterListByID(pID); // static method called
List<Y> listY = Y.GetParameterListByID(pID); // static method called
Upvotes: 3