views:

204

answers:

3

I'm trying to clean-up after an exception, and I'm not sure how to handle a StreamWriter.

Dim sw As StreamWriter

Try 
    ''// stuff happens

    somethingBad1() ''//Sometimes throws an exception

    sw = New StreamWriter(File.Open("c:\tmp.txt", FileMode.Create))

    ''// stuff happens

    somethingBad2() ''//Also sometimes throws an exception

    sw.Write("Hello World")
    sw.Flush()  ''//Flush buffer
    sw.Close()  ''//Close Stream

Catch ex As Exception
    sw = Nothing       
Finally
    sw = Nothing       
end try

If somethingBad1 throws an exception, I don't need to do anything to sw; however, if somathignBad2 happens, sw has already been created and I need to close it. But How do I know if sw has been created or not?

+8  A: 
''//stuff happens but you don't care because you didn't instantiate 
''//              StreamWriter yet
somethingBad1() ''//Sometimes throws an exception

Using sw As New StreamWriter("test.dat")
    ''// stuff happens
    somethingBad2() ''//Also sometimes throws an exception
    ''//as you are in a using statement the sw.Dispose method would be called
    ''//which would free the file handle properly
    sw.Write("Hello World")
End Using
Darin Dimitrov
+2  A: 

Only do the try after assigning the sw variable (in your sample). Or use a using statement.

But as a general rule, you should close the StreamWriter (if not using it with using), and not just assign Nothing to it. Also, catching all exceptions should be avoided, only handle exception which you know how to handle gracefully.

Lucero
+1  A: 

Darin has it right, but just one stylistici point to expand on Pavel Minaev's comment: unlike VB6, in VB.Net setting your sw reference to Nothing has no real effect. You really don't need to do it. What you could do is have code like this in your finally block:

Finally
    ''# test
    If sw IsNot Nothing Then sw.Dispose()
End

And that would take care of all the required cleanup (including what you've show of the catch block). You wouldn't even need to close the stream in your main code. But Using blocks are normally the better way to handle this.

Joel Coehoorn
I think that _was_ what I was looking for (+1), but I agree the "Using" block is a better method. btw., What's the background story to the "''//" convention for VB comments instead of just plain "'"? Was there a S.O. standard that I've missed?
CodeSlave
The built-in syntax highlighter chokes on the ' character in VB; it thinks it's the beginning of a string literal. You could also just put another ' character at the end of your lines, but then they are colored like string literals rather than comments and you have to also escape any other ' characters in your comment. Using ''// fixes it to color the line correctly as comment regardless of what other characters the line may contain.
Joel Coehoorn
As I've just discovered (and you can see above), you can also use ''# to save one character and not have it look like a C-style comment. In fact, I think I'll start using that from here on.
Joel Coehoorn