堆叠使用语句与单独使用语句

时间:2018-08-30 09:01:53

标签: c# performance using-statement

在重构代码时,我偶然发现了一些堆叠的using语句(我说的是10到15位数)。

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
}

类示例类似于

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;
  }
}

我首先想到的是,知道using基本上是try{} finally{ x.Dispose(); },使用连接将保持打开/活动状态,直到using块中的代码完成时为止只需要填写一个列表。

以上是我的假设,如果我错了,请纠正我。 考虑到我说的是正确的,写这样的东西会更好(性能,但主要是良好的实践方式)

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

还是它可以忽略不计,除了堆叠的using语句使嵌套的代码看起来不那么重要之外?

3 个答案:

答案 0 :(得分:3)

  

会更好(明智的选择)

,这取决于使用中使用的类型。您不能作一般性声明。

性能不是唯一因素,开放资源可能会阻塞其他进程或导致内存问题。但是另一方面,使用更紧凑的第一个版本可以提高可读性。因此,您必须确定是否存在问题。如果没有,何必呢?然后选择最佳的可读性和可维护性代码。

但是您可以重构代码,使用一种方法封装使用方法:

// in class X:
public static List<X> GetParameterListByID(int pID)
{
    using(X x = new X())
    { 
       return x.GetParameterListByID(pID);
    }
} 
// and same in other classes

现在该代码已不再使用:

List<X> listX = X.GetParameterListByID(pID); // static method called
List<Y> listY = Y.GetParameterListByID(pID); // static method called

答案 1 :(得分:2)

除了Tim所说的那样,许多数据库驱动程序还通过重用旧的驱动程序来使用“连接池”来提高连接性能。因此,在连接上调用Dispose时,它们并不会真正关闭(除非满足某些条件后),但是它们会为以后的调用保持空闲状态。

https://docs.microsoft.com/en-us/dotnet/framework/data/adonet/connection-pooling

答案 2 :(得分:1)

为什么不对所有查询使用1个连接?

我认为这将是一个更优雅的解决方案。

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);
    }
}