using
块绝对有用:单个块将仅在其自己的变量上调用Dispose
,而不是在同一块内部可能打开的其他变量上调用。这就是为什么要在程序的定义点清除的每个变量(应该是实现IDisposable
类型的每个变量)都需要自己的using
块。关于资源密集型操作(例如,打开数据库连接)的最佳实践的共识似乎是使用Using
块,因为Using
块"guarantees disposal of the resource... even in the case of an unhandled exception."。
这是我发现的大多数示例的书写方式:
Sub ExecuteCommand(ByVal sql As String, ByVal connectionString As String)
Using connection As New SqlConnection(connectionString)
Dim command As New SqlCommand(sql, connection)
command.Connection.Open()
command.ExecuteNonQuery()
End Using
End Sub
但是嵌套的Using
块是允许的,我偶尔(但很少)看到上面写为:
Sub ExecuteCommand(ByVal sql As String, ByVal connectionString As String)
Using connection As New SqlConnection(connectionString)
Using command As New SqlCommand(sql, connection)
command.Connection.Open()
command.ExecuteNonQuery()
End Using
End Using
End Sub
我的问题:多个嵌套Using
块有什么好处?还是单一的Using块已经保证它包含的所有资源都将被处置?
((注意:我的代码在VB.NET中,但是相同的问题也适用于C#。)
using块“即使在未处理的异常情况下也保证资源的使用...。”>。 politeness可以进行处置,将稀缺的资源返回到池中供其他人使用。此外,让我确保这一点很明确:把那“保证金”和一粒盐一起拿。许多事情都会阻止资源的处置。如果using块包含无限循环怎么办?还是该块引发了异常,堆栈上较高级别的敌对异常过滤器进入了无限循环,并且从未将控制权返回给与using语句关联的finally块?还是该块调用Environment.FailFast?有很多事情可能会阻止废物处置的进行。
切勿编写依赖其正确性处置的程序
真正未处理的异常是C#中实现定义的行为
。using
块的finally子句用于处理在使用块然后在其他地方处理]中引发异常的情况,而不是处理在块和从不处理。如果发生这种情况,则完全取决于实现来确定发生了什么。 C#语言对引发从未处理的异常的程序的行为做出的承诺总计为零。资源可能会被处置。他们可能不会。您所在的建筑物即将被意外拆除;您是否真的想花时间洗碗并整齐地存放它们?多个嵌套的Using块有什么好处?
是
单个Using块是否已经保证它包含的所有资源都将被处置?
没有仅清除using语句实际提及的资源。这就是为什么要嵌套它们。
在某些情况下,从技术上讲您不必这样做,因为内部资源负责释放与外部资源相同的资源。但是,使用块嵌套不会对您造成任何伤害,并且使读者很清楚发生了什么事情。这里的最佳实践是对要清除的每个资源都有一个using语句。
using
块绝对有用:单个块将仅在其自己的变量上调用Dispose
,而不是在同一块内部可能打开的其他变量上调用。这就是为什么要在程序的定义点清除的每个变量(应该是实现IDisposable
类型的每个变量)都需要自己的using
块。Using
语句将处理在Using
行中声明的变量。它对块中其他位置声明的变量没有影响。您应始终对每个一次性变量使用Using
语句。
如果对象是同一类型,则c#编译器提供了一种方法(语法糖),可以在单个using
语句内联中使用多个对象。
C#版本
using (MemoryStream ms1 = new MemoryStream(), ms2 = new MemoryStream())
{
}
Vb.Net版本
Using ms1 = New MemoryStream(), ms2 = New MemoryStream() End Using
这将同时处理两个MemoryStream
using
语句非常有用。但是,许多程序员并不认为SqlCommand
对象需要进行资源清理。也就是说,资源是连接,而不是命令。已添加
SqlCommand没有Close()方法,因此,即使SqlCommand具有Dispose()方法,缺少Close()方法也表明实际上没有任何东西可以关闭/释放。一次性实例最终将始终被处置。很难找到权威的东西,而无需深入研究源代码,但是当在this article中被问及MS家伙确切地处置了它时,他说“实际上并不多...”,并继续为SqlCommand建议USING子句( ),所以我正确回答了这个问题,但最初避免了它背后的模糊性。
using
块绝对有用:单个块将仅在其自己的变量上调用Dispose
,而不是在同一块内部可能打开的其他变量上调用。这就是为什么要在程序的定义点清除的每个变量(应该是实现IDisposable
类型的每个变量)都需要自己的using
块。Using
语句将处理在Using
行中声明的变量。它对块中其他位置声明的变量没有影响。using
语句非常有用。但是,许多程序员并不认为SqlCommand
对象需要进行资源清理。也就是说,资源是连接,而不是命令。