.NET函数范围阴影

w00*_*977 1 .net vb.net asp.net

我见过这样的代码(不是在连续的行上,而是在相同的函数范围内):

Dim con1 As SqlConnection
con1 = New SqlConnection
'More code here
con1 = New SqlConnection
con1 = Nothing
Run Code Online (Sandbox Code Playgroud)

我相信这只是一个错误,但我想检查一下我没有意识到这里没有一种形式的阴影.第一个con1变量会发生什么?我认为它是无法访问的,因为没有对象的引用.

Eri*_* J. 5

这里发生了什么事

con1 在该函数的生命周期内指向两个不同的对象.

第一个对象,由第一个创建

con1 = New SqlConnection
Run Code Online (Sandbox Code Playgroud)

在第二个之后不再引用

con1 = New SqlConnection
Run Code Online (Sandbox Code Playgroud)

被执行.

这是内存泄漏吗?

不会.不再引用的对象最终将被处理掉,然后GC决定这样做.然而,这一个资源泄漏.每次无法关闭SQL连接(假设它已打开而不仅仅是已分配),您将使资源无法重用.当GC会触发内存低,所以你一定会恢复未引用的对象的内存最迟当系统内存不足(也将重新获得在该点的数据库连接).然而,低资源不会触发GC.在GC决定启动并释放SqlConnection对象(包括他们正在囤积的数据库连接)之前,您可以完全运行数据库连接.

修复代码

由于必须关闭SqlConnection以释放连接,因此第一个对象将一直挂起,直到GC决定丢弃它. 这是一件坏事,因为SQL连接是一种资源,只有在必要时才能保留.

在分配新的SqlConnection对象之前调用Close()第一个连接将改善这种情况(同样,在离开变量范围之前调用第二个实例上的Close()).

但是,如果在代码中的某处出现异常,没有适当的异常处理,那么在GC启动之前,您仍然会留下未处置的对象.总是,总是将异常处理放在管理资源的任何事情上.

为此场景设置异常处理的最佳方法是使用Using关键字.到目前为止,我从未写过一行VB.Net,但这是我尝试使用正确版本的代码:

Dim con1 As SqlConnection

Using con1
    con1 = New SqlConnection
End Using

'More code here

Using con1
    con1 = New SqlConnection
End Using

' NOTE: I believe the following is unnecessary, but was necessary in VB6 and prior
' con1 = Nothing 
Run Code Online (Sandbox Code Playgroud)