7

我在 MSDN 网站上找到了这段代码http://msdn.microsoft.com/en-us/library/system.data.sqlclient.sqlconnection.open.aspx

private static void OpenSqlConnection(string connectionString)
{
    using (SqlConnection connection = new SqlConnection(connectionString))
    {
        connection.Open();
        Console.WriteLine("ServerVersion: {0}", connection.ServerVersion);
        Console.WriteLine("State: {0}", connection.State);
    }
}

我的问题是......该网站还指出,.Open()可以抛出 InvalidOperationExceptions 和 SqlExceptions,但这个例子看起来不像它处理它们。

这仅仅是因为他们对代码很简短,还是因为他们不值得在这里处理?它们是否可能以某种方式由 using 构造处理?

4

7 回答 7

9

这仅仅是因为他们对代码很简短,还是因为他们不值得在这里处理?它们是否可能以某种方式由 using 构造处理?

using关键字是语法糖,try/finally即使您引用的代码不会处理可能的异常,SQL 连接也会被正确处理。他们可能没有明确地处理可能的异常,因为许多人更喜欢让异常冒泡到最高层并在那里处理异常。

于 2012-04-30T14:22:00.987 回答
4

MSDN 示例旨在提供易于阅读的示例,而不是教授最佳实践。这就是人们不应该在不理解代码的情况下复制/粘贴代码的原因之一。

根据 MSDN

using 语句以正确的方式调用对象的 Dispose 方法,并且(当您如前所示使用它时)它还会导致对象本身在调用 Dispose 时立即超出范围。

它将关闭打开的连接(通过使用 finally)。它不会捕获抛出的异常。它通过将随附的语句包装在 try/finally 中来实现。没有问题。

于 2012-04-30T14:20:52.893 回答
3

这取决于在捕获这些异常时是否可以“做”任何事情。

如果不是 - 它通常被认为是让异常在堆栈中冒泡的最佳实践,直到它们达到可以以有意义的方式处理它们的地步(在网络应用程序的情况下,这可能只是记录 500 错误)

于 2012-04-30T14:20:43.203 回答
2

这些案件正在处理中。

using语句被转换为适当的处置模式,该模式还可以处理异常情况下的处置。

在这种情况下,即使抛出异常,连接也会被丢弃。

异常本身会冒泡。

有关详细信息,请参阅MSDN 上的使用声明

于 2012-04-30T14:21:09.600 回答
1
using (SqlConnection connection = new SqlConnection(connectionString))
    {

    }

相当于

try
{

    SqlConnection connection = new SqlConnection(connectionString)
}
finally
{
   connection.Dispose();
}

“使用”只是为了确保调用对象上的 dispose() 方法(在这种情况下,确保连接返回到连接池)。“使用”从来都不是用来代替 catch 的。

在我从事过的项目中,通常我们最终都会进行很多尝试。Catch 仅在最高级别用于记录它。不应该使用 catch 来重新抛出错误(而不是记录错误)的原因之一是 catch 非常耗费资源。

于 2012-04-30T14:34:57.920 回答
0

using 语句确保即使在调用对象上的方法时发生异常,也会调用 Dispose。Try/catch 的开销很大。try/catch 会影响编译器优化以及程序员会使用 try/catch 来做一些简单的事情,比如检查 null。这只是不好的做法。捕获异常总是比进行简单检查要慢。我并不是说要使用它们,而是不要使用它们来代替防御性编程。

此外,查看代码“打开”命令只有在存在有效连接时才会被调用..所以不用担心....

“使用”与将对象放在 try 块中,然后在 finally 块中调用 Dispose 相同。

如果您仍需要处理任何特定异常,请包含 try..catch..

于 2012-04-30T14:29:39.900 回答
0

此示例令人困惑,但在技术上是正确的。在现实世界的应用程序中,此示例“按原样”没有任何价值。
他们甚至不将 SqlConnection 返回给调用代码。
因此,正如您所说,“他们对代码很简短”。

在现实世界的场景中,你可以有这样的方法

private static SqlConnection OpenSqlConnection(string connectionString) 
{ 
    SqlConnection connection = new SqlConnection(connectionString)
    connection.Open(); 
    return connection;    
} 

然后在你的代码中使用它(虽然没有什么收获)

using(SqlConnection cnn = OpenSqlConnection(connectionString))
{
    // Do your work here
    ....
}

当然 using 语句隐藏了所有工作以捕获异常并关闭/处理所有内容,因此,从技术上讲,异常已被处理,实际上,如果出现故障,您不会得到任何线索。

于 2012-04-30T14:33:51.977 回答