你是否应该在使用区块内调用close

时间:2011-03-22 16:51:04

标签: vb.net

Using sr As New System.IO.StreamWriter("C:\test.txt")
   sr.WriteEnd
End Using
Using sr As New System.IO.StreamReader("C:\test.txt")
   sr.ReadToEnd
End Using

这相当于:

sr = New System.IO.StreamWriter("C:\test.txt")
sr.WriteEnd
sr.Dispose
sr = New System.IO.StreamReader("C:\test.txt")
sr.ReadToEnd
sr.Dispose

我是否正确地说,如果垃圾收集器没有处理StreamWriter并关闭文件,则尝试读取文件可能会失败。如果是这样,那么在这种情况下使用Using语句的好处在哪里。使用

是更好的做法
Using sr As New System.IO.StreamWriter("C:\test.txt")
       sr.WriteEnd
sr.close()
    End Using

4 个答案:

答案 0 :(得分:5)

始终使用Using语句是最佳做法,因为如果在读取期间抛出异常,则可能永远不会处理流,并且您的应用程序将泄漏文件句柄。如果这是一个桌面应用程序,该进程可能会死并释放句柄,但在Web应用程序中不释放非托管资源(如文件句柄)可能是灾难性的。

如果您拨打Close,也无需在信息流中致电Dispose

备注:如果您想将文本文件的内容读入字符串,您可以直接执行此操作,而不是经历实例化StreamReader的痛苦,将其读取到最后并将其处理:

Dim data = File.ReadAllText("C:\test.txt");

答案 1 :(得分:2)

不,垃圾收集器处理该对象,调用Dispose会这样做,而使用块确保发生这种情况。该对象可能仍在内存中,但该文件已被处理。

如果你没有调用close或dispose(手动或使用using块),并且收集了对象,那么它将被最终确定(减慢垃圾收集)关闭文件句柄。但这种最后机会与处置不同。

你没有拥有来对使用区块内的文件进行关闭,但你可以自由选择。这可能是一个很好的想法来快速释放句柄(通常不是文件句柄的问题,更常见的是池数据库连接的问题),使用块为您提供额外的保证(调用dispose始终是安全的,即使它的已被召集过。)

答案 2 :(得分:2)

实际上,它等同于:Finally块将保证调用Dispose,并在发生异常时清除所有内容。

    Try
        sr = New System.IO.StreamWriter("C:\test.txt")
        sr.WriteEnd()
    Finally
        sr.Dispose()
    End Try
    Try
        sr = New System.IO.StreamReader("C:\test.txt")
        sr.ReadToEnd()
    Finally
        sr.Dispose()
    End Try

答案 3 :(得分:0)

想想你是否已经完成并且过于关心它,可以让配置刚刚发生 处置可能需要一段时间,因此如果您需要使用该文件(例如,传递到另一个应用程序,移动到新位置,或任何其他文件使用),那么可能应该明确地关闭它

关闭应该释放任何锁,期望这将失败:

dim fn as string = "C:\temp.txt"
Using sr As New System.IO.StreamWriter(fn)
    sr.WriteLine("Junk")
    ' sr.close
End Using
system.io.file.delete(fn)

预计删除会抛出错误,因为文件处理可能尚未发生 如果您明确关闭(例如取消评论关闭),则应始终成功