0

我想知道以下代码模式:

    static SqlConnection getcon()
    {
        SqlConnection con = new SqlConnection("data source=foobar..");
        con.Open();

        // is con Disposed automatically or will it leak and live 
        // forever when exception is thrown?

        throw new Exception("exception");
        return con;
    }

    static void Main(string[] args)
    {
        try 
        {
            using (var scope = new TransactionScope())
            using (var con = getcon())
            using (var cmd = new SqlCommand("UPDATE SomeTable SET Column1 = 'test'", con))
            {                   
                cmd.ExecuteNonQuery();

                scope.Complete();
            }
        }
        catch     
        {
        }
    }

这是一种安全的使用方式SqlConnection(从方法获取连接getcon())吗?当抛出异常时,它会在函数退出后被释放还是会永远存在?

我想要这种GetCon()方法的目的是缩短代码并将连接创建和打开包装在一行中(using (var con = getcon())..)

4

3 回答 3

2

您编写 getcon 方法的方式(我假设您是专门为测试某些东西而编写的), con 将在抛出异常的那一刻被释放。由于'return con;' 在您抛出异常之后,它将永远不会返回给调用代码,并且会在 getcon 退出后立即被释放(超出范围)。

于 2013-08-05T20:31:14.320 回答
2
is con Disposed automatically or will it leak and live orever when exception is thrown?

throw new Exception("exception");
return con;//your code

实际上return con;线路是无法到达的。换句话说,它永远不会在这里执行。你没有返回con方法实际上是通过抛出一个Exception. 所以你的连接不会被清理here

当方法退出(异常)时,局部变量不在Scope并且您没有对其的托管引用,因此显然您conGarbage Collection.

will it leak and live orever when exception is thrown?

答案是否定的,垃圾收集器将负责回收所使用的内存,Connection并且Dispose(true)通常从Finalizer.

编辑

假设您的 get con 方法没有抛出任何异常并返回 aConnectionException抛出如下

using (var scope = new TransactionScope())
using (var con = getcon())
using (var cmd = new SqlCommand("UPDATE SomeTable SET Column1 = 'test'", con))
{
    throw new Exception("Oops");//Throw excception somewhere here             
    cmd.ExecuteNonQuery();
    scope.Complete();
}

上面的代码将保证在抛出异常时进行清理,因为您包装conusing语句中。

希望这可以帮助

于 2013-08-05T20:52:30.353 回答
1

我认为 jaadooviewer 的回答是正确的,但您似乎可以通过在 getcon 方法中使用 try/catch 块来完全避免这个问题。

try
{
    SQLConnection con = new SQLConnection("...");
    con.Open();
    if (/*condition*/)
        throw new Exception("Exception Condition Satisfied");
}
catch (Exception ex)
{
    con.Dispose();
    throw ex;
}
return con;
于 2013-08-05T20:37:49.817 回答