Reputation:
If I initialize a class with the Using
statement, is it necessary to call it's Close method upon early termination?
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
Upvotes: 1
Views: 153
Reputation: 112482
The decompiler shows that the Dispose
method called at the end of the Using
-statement is implemented like this:
Public Sub Dispose() Implements IDisposable.Dispose
Me.Close()
End Sub
It is implemented by the base class System.IO.Stream
.
However, since you are calling Environment.Exit(-1)
the code is aborted and the Dispose
method is NOT called! You can test it with this class:
Class Disp
Implements IDisposable
Public Sub Dispose() Implements IDisposable.Dispose
MsgBox("Disposing")
End Sub
End Class
and this code:
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
It should display "Disposing" in a message box, but doesn't! If you comment out Environment.Exit(-1)
the message is displayed.
The Using
statement is implemented as a Try Finally
statement, so your code is equivalent to two nested Try ... End Try
blocks. Microsoft's documentation for the Environment.Exit Method says: "... If Exit is called from a try or finally block, the code in any catch block does not execute. ...". But the documentation is unclear on whether the finally block is executed or not. The documentation for Try...Catch...Finally Statement, however, says:
Control does not pass from a Try or Catch block to the corresponding Finally block in the following cases:
•An End Statement is encountered in the Try or Catch block.
•A StackOverflowException is thrown in the Try or Catch block.
And the documentation for the End Statement says: "The End statement calls the Exit method of the Environment class in the System namespace. ...".
Finally, putting these informations together, we can say:
Yes you must call xmlstream.Close()
before calling Environment.Exit(-1)
!
See also: Calling Environment.Exit() Within a Using Block
Upvotes: 0
Reputation: 27342
Not it is not necessary. According to the IDisposable.Dispose Method documentation
"The using statement automatically closes the stream and calls Dispose on the object when the code that is using it has completed"
Having said that it is not a good idea to have Environment.Exit
within a Using block as this does not call Close
, or indeed Dispose
. Instead you should refactor this as a function that returns True or False and act on that return value to decide whether to Exit or not
Upvotes: 3
Reputation: 970
As a sugestion, you can rewrite in this way. About, what you asked, the program will leave the closure of the method to the O.S.
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
Upvotes: 1