C#SQL连接try / catch vs using vs try / catch w / using

C# SQL Connection try/catch vs using vs try/catch w/ using

我是第三代在组织内的系统上工作的人,当然编程风格也存在差异。我想知道连接到数据库的正确方法是什么,因为系统中使用了两种不同的样式。那么,"正确"的方法是什么呢?

方法1:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
try
{
    using (SqlConnection con = new SqlConnection(connectionString))
    {
        con.Open();

        using (SqlCommand command = new SqlCommand("StoredProcedure", con))
        {
            command.CommandType = CommandType.StoredProcedure;
            command.Parameters.Add(new SqlParameter("foo", bar));
        }

        using (SqlDataReader reader = command.ExecuteReader())
        {  
            //do stuff
        }
    }
}
catch (Exception ex)
{
    //do stuff
}

方法2:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
// Variables
SqlCommand loComm;
SqlConnection loConn = null;
SqlDataReader loDR;

try
{
    // Init command
    loComm = new SqlCommand("foo");
    loComm.CommandType = CommandType.StoredProcedure;
    loComm.Parameters.AddWithValue("foo", bar);

    // Init conn
    loConn = new SqlConnection(String);
    loConn.Open();
    loComm.Connection = loConn;

    // Run command
    loDR = loComm.ExecuteReader();

    //do stuff          
}
catch (Exception ex)
{
    //do stuff
}

虽然这两种方法都有效,但我不确定哪种方法最适合使用。有没有理由用一个比另一个?第二个方法对我来说更清晰、更容易理解,但它不会在完成后自动运行idispose()函数。

编辑:我的问题不同于建议的问题,因为一种方法使用"using"语句,而另一种方法不使用。因此我的问题直接关系到在进行数据库连接时是否使用"using"语句。

谢谢你的回复。


方法2是完全错误的,应该修复。

完成后,您将得到尚未处理的IDisposable实例。最有可能的是,这会破坏与SqlConnection幕后进行的连接管理,特别是在GC决定介入之前,这段代码会被反复处理。

如果一个实例是IDisposable,那么它需要是Disposed,最好是在尽可能小的范围内。使用using将确保发生这种情况,即使代码出现故障和抛出异常。

一份using声明:

1
2
3
4
using(var disposableInstance = new SomeDisposableClass())
{
    //use your disposable instance
}

是(提供或采取一些小细节)句法糖用于:

1
2
3
4
5
6
7
8
9
10
var disposableInstance = new SomeDisposableClass();
try
{
    //use your disposable instance
}
finally
{
    //this will definitely run, even if there are exceptions in the try block
    disposableInstance.Dispose();
}

即使try区块出现问题,也可以确保执行finally区块,从而确保无论发生什么情况,都能处置您的可处置资产。


在第一个示例中,如果抛出了异常,则将正确关闭和处理包装在using块中的对象。

在第二种情况下,您将需要手动处置对象。

另一件值得一提的事情是,如果您计划只在抛出异常时处理对象,那么您将拥有未处理的对象,因此您需要实现一个try..catch..finally,并在finally块内处理对象。

第一个是更好的选择。


读到这里,它说:

As a rule, when you use an IDisposable object, you should declare and instantiate it in a using statement. The using statement calls the Dispose method on the object in the correct way, and (when you use it as shown earlier) it also causes the object itself to go out of scope as soon as Dispose is called. Within the using block, the object is read-only and cannot be modified or reassigned.

The using statement ensures that Dispose is called even if an exception occurs while you are calling methods on the object. You can achieve the same result by putting the object inside a try block and then calling Dispose in a finally block; in fact, this is how the using statement is translated by the compiler.

听起来正确的方法是方法1。


using块所做的是保证无论是否引发异常,都将始终调用对象Dispose方法。

Dispose是一种清理资源的方法。在数据库连接的情况下,连接被释放,这非常重要。

因此,在这种情况下,正确的方法是使用using模式。

using父对象之间包含的对象必须是IDisposable,这意味着它有一个Dispose方法,当不再需要该对象时应该调用该方法。如果不调用Dispose,则在垃圾收集器销毁对象时,将在任何不确定的时间对其进行处理。这是不可取的情况下,如数据库连接,必须尽快关闭。

usin的等价物是try finally,其中包括在finally块内调用Dispose


如果抛出异常,第一个将关闭连接。第二个不会,所以我要说,选择第一个。