34

Possible Duplicate:
try/catch + using, right syntax

I would like to try/catch the following:

//write to file
using (StreamWriter sw = File.AppendText(filePath))
{
    sw.WriteLine(message);
}

Do I put the try/catch blocks inside the using statement, or around it, or both?

Ryan R
  • 8,342
  • 15
  • 84
  • 111

3 Answers3

53

If your catch statement needs to access the variable declared in a using statement, then inside is your only option.

If your catch statement needs the object referenced in the using before it is disposed, then inside is your only option.

If your catch statement takes an action of unknown duration, like displaying a message to the user, and you would like to dispose of your resources before that happens, then outside is your best option.

Whenever I have a scenerio similar to this, the try-catch block is usually in a different method further up the call stack from the using. It is not typical for a method to know how to handle exceptions that occur within it like this.

So my general recomendation is outside—way outside.

private void saveButton_Click(object sender, EventArgs args)
{
    try
    {
        SaveFile(myFile); // The using statement will appear somewhere in here.
    }
    catch (IOException ex)
    {
        MessageBox.Show(ex.Message);
    }
}
Jeffrey L Whitledge
  • 58,241
  • 9
  • 71
  • 99
16

I suppose this is the preferred way:

try
{
    using (StreamWriter sw = File.AppendText(filePath))
    {
        sw.WriteLine(message);
    }
}
catch(Exception ex)
{
   // Handle exception
}
CD..
  • 72,281
  • 25
  • 154
  • 163
11

If you need a try/catch block anyway then the using statement is not buying you much. Just ditch it and do this instead:

StreamWriter sw = null;
try
{
    sw = File.AppendText(filePath);
    sw.WriteLine(message);
}
catch(Exception)
{
}
finally
{
    if (sw != null)
        sw.Dispose();
}
hemp
  • 5,602
  • 29
  • 43
  • 5
    Very horrid code. There is no reason to give up the convenience (readability, simplicity) of the using block. – H H May 26 '11 at 21:40
  • 17
    @Henk: You do realize that's an entirely subjective opinion? I happen to think finally blocks are readable, convenient and simple. The using statement is nice syntactic sugar when it makes sense, but in this case it does not make sense. – hemp May 26 '11 at 21:58
  • 1
    No it's not entirely subjective. You've got about 4 extra lines dealing with 'sw', and it's in a wider scope. I think it takes about 2-3 times the effort to _read and comprehend_. That sucks. And there is a link-up with the try/catch that suggests a relation that in 99% of situations isn't there. – H H May 26 '11 at 22:02
  • Agreed.. There is no reason not to use a using statement just because you want to catch an exception. The using statement is to identify to the developer as well as GC that the dispose should occur and in a timely matter! – gcoleman0828 Sep 16 '13 at 21:30
  • 10
    Correction: the using statement tells the GC nothing. It is unrolled (by the C# compiler) into a try/finally (in IL) that contains a call to the object's IDisposable.Dispose() method implementation. It does serve as an indicator to the developer that the dispose should occur, similar to the way explicitly calling Dispose in a finally block indicates that the dispose should occur. – hemp Sep 24 '13 at 05:08
  • 1
    Ok... that is correct, the point was that the GC disposes of it much faster this way regardless of the way it happens. The above code is less elegant and more prone to error by forgetting the finally statement as many developers do. From MSDN "The using statement ensures that Dispose is called even if an exception occurs while you are calling methods on the object." – gcoleman0828 Sep 26 '13 at 12:03
  • 9
    One is no more likely to forget to call dispose in a finally block than one is to forget to wrap the object in a using block (as many developers do). From MSDN "The finally block is useful for cleaning up any resources..." I think we've beat this one thoroughly to death. – hemp Sep 26 '13 at 19:32
  • 5
    @hemp is pretty much correct throughout this discourse. While I would still encourage `using` even inside of try/catch simply for the sake of consistency, if programmers don't know they should be disposing of an object, then neither pattern is going to matter. This deals purely with preference, which by definition is subjective. I do like the idea of putting it in the `finally` block here, but I won't simply because I'm afraid of confusing other programmers who might not understand. – crush Nov 24 '14 at 17:37
  • 2
    From MSDN Coding Conventions: "If you have a try-finally statement in which the only code in the finally block is a call to the Dispose method, use a using statement instead." – Bugalugs Nash Jul 10 '15 at 00:19
  • 2
    Of course. However, a try-finally statement is not the same as a try-catch-finally statement. – hemp Jul 21 '15 at 22:06
  • @hemp Glad I found your arguments! – chadiik Feb 26 '17 at 16:16