【问题标题】:Is it necessary to call "Close" when within 'using' statement upon early process termination?是否有必要在进程提前终止时在“使用”语句中调用“关闭”?
【发布时间】:2014-09-08 14:03:10
【问题描述】:

如果我用Using 语句初始化一个类,是否有必要在提前终止时调用它的 Close 方法?

Using xmlstream As New MemoryStream()
    Try
        'Do runtime operation

    Catch ex As Exception
        Console.WriteLine("Could not fill dataset.  REASON: " & ex.Message)
        xmlstream.Close()  '<-  NECESSARY????
        Environment.Exit(-1) '<- Early termination!
    End Try
    'DO STUFF
End Using

【问题讨论】:

  • 不,最终使用会满足它

标签: .net vb.net dispose using-statement


【解决方案1】:

不是没有必要。根据the IDisposable.Dispose Method documentation

“当正在使用它的代码完成时,using 语句会自动关闭流并在对象上调用 Dispose”

话虽如此,在 Using 块中包含 Environment.Exit 并不是一个好主意,因为这不会调用 Close,或者实际上是 Dispose。相反,您应该将其重构为一个返回 True 或 False 的函数,并根据该返回值来决定是否退出

【讨论】:

  • 好。不用担心调用 close 方法很方便。
  • @OlivierJacot-Descombes 这就是我在上一段中所说的
【解决方案2】:

作为建议,您可以以这种方式重写。关于,你问什么,程序会将方法的关闭留给操作系统

Try

          Using xmlstream As New MemoryStream()
          'Do runtime operation


         End Using

Catch ex As Exception
                        Console.WriteLine("Could not fill dataset.  REASON: " & ex.Message)         
                        Environment.Exit(-1)
                    End Try
                    'DO STUFF

【讨论】:

    【解决方案3】:

    反编译器显示Using-statement末尾调用的Dispose方法是这样实现的:

    Public Sub Dispose() Implements IDisposable.Dispose
        Me.Close()
    End Sub
    

    由基类System.IO.Stream实现。

    但是,由于您正在调用Environment.Exit(-1),因此代码被中止并且Dispose 方法未被调用!你可以用这个类来测试它:

    Class Disp
        Implements IDisposable
        Public Sub Dispose() Implements IDisposable.Dispose
            MsgBox("Disposing")
        End Sub
    End Class
    

    还有这段代码:

    Private Sub btnTest_Click(ByVal sender As Object, ByVal e As EventArgs) Handles btnTest.Click
        Dim x = 100, y = 0, z = 0
        Using d = New Disp()
            Try
                z = x \ y
            Catch ex As Exception
                Environment.Exit(-1)
            End Try
        End Using
    End Sub
    

    它应该在消息框中显示“正在处理”,但没有!如果您注释掉Environment.Exit(-1),则会显示该消息。

    Using 语句实现为Try Finally 语句,因此您的代码相当于两个嵌套的Try ... End Try 块。微软的Environment.Exit Method 文档说:“......如果从 try 或 finally 块调用 Exit,则任何 catch 块中的代码都不会执行......”。但是文档不清楚 finally 块是否被执行。但是,Try...Catch...Finally Statement 的文档说:

    在以下情况下,控件不会从 Try 或 Catch 块传递到相应的 finally 块:

    •在 Try 或 Catch 块中遇到 End 语句。

    •在 Try 或 Catch 块中引发 StackOverflowException。

    End Statement 的文档说:“End 语句调用 System 命名空间中 Environment 类的 Exit 方法。...”。

    最后,将这些信息放在一起,我们可以说:
    是的,您必须先致电xmlstream.Close(),然后再致电Environment.Exit(-1)

    另见:Calling Environment.Exit() Within a Using Block

    【讨论】:

      猜你喜欢
      • 2014-06-18
      • 2023-03-27
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-09-06
      • 1970-01-01
      • 2021-12-08
      相关资源
      最近更新 更多