Harold Hemms
Harold Hemms

Reputation: 44

Stacked using statements vs seperate using statements

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

Answers (3)

Ghasan غسان
Ghasan غسان

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

Piftje
Piftje

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

Tim Schmelter
Tim Schmelter

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

Related Questions