Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/332.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 在引发异常时处理SqlConnection_C#_Sqlconnection - Fatal编程技术网

C# 在引发异常时处理SqlConnection

C# 在引发异常时处理SqlConnection,c#,sqlconnection,C#,Sqlconnection,我想知道以下代码模式: 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 th

我想知道以下代码模式:

    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()
方法的目的是缩短代码,并将连接的创建和打开包装在一行中(
使用(var-con=GetCon())

您编写GetCon方法的方式(我假设您是专门为了测试某个东西),一旦抛出异常,con就会被释放。自“return con;”起是在您抛出异常之后,它将永远不会返回到调用代码,并将在getcon退出时被释放(用于超出范围)。

按照您编写getcon方法的方式(我假设您这样做是专门为了测试某些内容),一旦抛出异常,con就会被释放。自“return con;”起是在您抛出异常之后,它将永远不会返回到调用代码,并将在getcon退出时被释放(用于超出范围)。

我认为Jaadoviewer的回答是正确的,但似乎您可以通过在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;

我认为Jaadoviewer的答案是正确的,但似乎可以通过在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;
实际
返回con行不可访问。换句话说,它永远不会在这里执行。您没有返回
con
方法,而是通过抛出
异常来实际退出。因此,您的连接将不会在此处清理

当方法退出时(异常情况下),局部变量超出了
范围,并且您没有对该变量的托管引用,因此显然您的
con
要进行
垃圾收集

will it leak and live orever when exception is thrown?
答案是否定的,垃圾收集器将负责回收
连接所使用的内存
,当
Dispose(true)
通常从
终结器
调用时,您的连接将关闭

编辑

假设您的get-con方法没有抛出任何异常,并返回一个
连接
,而
异常
被抛出,如下所示

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();
}
上述代码将保证在抛出异常时进行清理,因为您使用
语句将
con
包装到

希望这有帮助

实际
返回con行不可访问。换句话说,它永远不会在这里执行。您没有返回
con
方法,而是通过抛出
异常来实际退出。因此,您的连接将不会在此处清理

当方法退出时(异常情况下),局部变量超出了
范围,并且您没有对该变量的托管引用,因此显然您的
con
要进行
垃圾收集

will it leak and live orever when exception is thrown?
答案是否定的,垃圾收集器将负责回收
连接所使用的内存
,当
Dispose(true)
通常从
终结器
调用时,您的连接将关闭

编辑

假设您的get-con方法没有抛出任何异常,并返回一个
连接
,而
异常
被抛出,如下所示

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();
}
上述代码将保证在抛出异常时进行清理,因为您使用
语句将
con
包装到


希望这有帮助

我已经编辑了你的标题。请看,“,其中的共识是“不,他们不应该”。好的!但是,即使异常发生在“using”行中,而不是在花括号{}中,连接是否也会被处理掉呢?为了避免键入一行代码(
conn.Open()
)而经历所有这些麻烦(可能会产生副作用和错误),这似乎是一种非常误导和过早的优化,不要这样做。这不值得。我已经编辑了你的标题。请看,“,其中的共识是“不,他们不应该”。好的!但是,即使异常发生在“using”行中,而不是在花括号{}中,连接是否也会被处理掉呢?为了避免键入一行代码(
conn.Open()
)而经历所有这些麻烦(可能会产生副作用和错误),这似乎是一种非常误导和过早的优化,不要这样做。这里的主要问题是Using-block是否在
getcon()
方法中扩展了它的触角not@Jaska-是的
getcon()
是在using块内调用的,因此可以说它在块内。您可能希望将
catch(Execption)
throw结合使用这样就不会丢失堆栈跟踪。(还有
Dispose()
隐式调用
Close()
用于
SqlConnection
,因此您不需要在catch块中调用它)我不确定第一条注释是什么意思。感谢您对第二个问题的澄清。这里的主要问题是Using-block是否在
getcon()
方法中扩展了它的触角not@Jaska-是的
getcon()
是在using块内调用的,因此可以说它在块内。您可能希望将
catch(Execption)
throw结合使用这样就不会丢失堆栈跟踪。(还有
Dispose()
隐式调用
Close()
用于
SqlConnection
,因此您不需要在catch块中调用它)我不确定第一条注释是什么意思。谢谢你对第二条的澄清。