如果在“using”语句中使用try/catch,那么可被释放的资源会被释放吗?

4

我正在使用 SqlConnectionSqlCommand

如果出现任何 SqlException,我必须捕获异常。

我使用了 using 语句,并在其中嵌套了一个 try/catch块。以下是代码:

public static void LogError(string error, string message)
{
    using (SqlConnection conn = new SqlConnection(ConfigurationManager.AppSettings["connStringWeb"]))
    using (SqlCommand cmd = new SqlCommand("INSERT INTO errorLogTable (errorTime, errorType, error) VALUES(@errorTime, @errorText, @errorMsg)"))
    {
        cmd.CommandTimeout = 300;
        cmd.Connection = conn;
        cmd.Prepare();
        cmd.Parameters.AddWithValue("@errorTime", DateTime.Now);
        cmd.Parameters.AddWithValue("@errorText", error);
        cmd.Parameters.AddWithValue("@errorMsg", message);

        try
        {
           conn.Open();
           int i = cmd.ExecuteNonQuery();
        }
        catch { }
        }
   }
}

我的问题是,如果出现异常,我的SqlConnectionSqlCommand会被处理掉吗?这种方法是否好处理呢?还是我应该使用传统的try/catch/finally块来处理它?

这是完全有效的。 - XtremeBytes
3个回答

5
using语句只是一个try/finally块的语法快捷方式。因此,在抛出异常的情况下,using内部的对象将被处理。换句话说:
using(var foo = new Foo())
{
}

本质上被编译为:

Foo foo;

try
{
    foo = new Foo();
}
finally
{
    foo.Dispose();
}

3
在你的情况下,异常被捕获在 using 中并且当你离开 using 块时会执行 dispose。但是即使你将 using 块放在 try catch 外部并且抛出异常,dispose 也会被调用。
public static void LogError(string error, string message)
{
    try
    {
        using (SqlConnection conn = new SqlConnection(ConfigurationManager.AppSettings["connStringWeb"]))
            using (SqlCommand cmd = new SqlCommand("INSERT INTO errorLogTable (errorTime, errorType, error) VALUES(@errorTime, @errorText, @errorMsg)"))
            {
                cmd.CommandTimeout = 300;
                cmd.Connection = conn;
                cmd.Prepare();
                cmd.Parameters.AddWithValue("@errorTime", DateTime.Now);
                cmd.Parameters.AddWithValue("@errorText", error);
                cmd.Parameters.AddWithValue("@errorMsg", message);

                conn.Open();
                int i = cmd.ExecuteNonQuery();
            }
    }
    catch {}
}

3

您可以在using块内或外使用try catch。在两种情况下,SqlConnection和SqlCommand都将被处理。

然而,我更喜欢将try catch放在using块外部以捕获所有错误,甚至包括对象创建错误。


允许像这样拥有两个“using”语句,而没有最外层的{...}块也是可以的(而不是“不正确的”)。从技术上讲,“using”不需要一个块;任何嵌入语句都可以。 - Jeppe Stig Nielsen
这与try语句不同,你必须在try之后使用一个代码块。 - Jeppe Stig Nielsen

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接