Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Try/Finally block vs calling dispose?

Is there any difference between these two code samples and if not, why does using exist?

StreamWriter writer;
try {
    writer = new StreamWriter(...)
    writer.blahblah();

} finally {
    writer.Dispose();
}

vs:

using (Streamwriter writer = new Streamwriter(...)) {
    writer.blahblah
}

I mean in the second example you really should be putting it in a try block anyway so adding the finally block really doesn't use much more effort. I get that the entire thing might be encompassed in a bigger try block but yeah, just seems superfluous to me.

like image 244
rollsch Avatar asked Dec 20 '13 12:12

rollsch


People also ask

Does try finally throw exception?

Yes, it absolutely will. Assuming your finally block doesn't throw an exception, of course, in which case that will effectively "replace" the one that was originally thrown.

Why do we need finally block in C#?

By using a finally block, you can clean up any resources that are allocated in a try block, and you can run code even if an exception occurs in the try block. Typically, the statements of a finally block run when control leaves a try statement.

Can we use try and finally without catch in C#?

The finally block does not contain any return, continue, break statements because it does not allow controls to leave the finally block. You can also use finally block only with a try block means without a catch block but in this situation, no exceptions are handled.

In which case finally block is not executed C#?

Answers. The only reason a finally block won't get executed is if the thread is terminated abnormally (other than a corrupted stack--but the MDAs should catch that).


2 Answers

There're some issues with your code. Please, never write like this (put using instead), and that's why:

StreamWriter writer;
try {
    // What if you failed here to create StreamWriter? 
    // E.g. you haven't got permissions, the path is wrong etc. 
    // In this case "writer" will point to trash and
    // The "finally" section will be executed
    writer = new StreamWriter(...) 
    writer.blahblah();
} finally {
    // If you failed to execute the StreamWriter's constructor
    // "writer" points to trash and you'll probably crash with Access Violation
    // Moreover, this Access Violation will be an unstable error!
    writer.Dispose(); 
}

When you put using like that

  using (StreamWriter writer = new StreamWriter(...)) {
    writer.blahblah();
  }

It's equal to the code

StreamWriter writer = null; // <- note the assignment

try {
  writer = new StreamWriter(...); 
  writer.blahblah();
}
finally {
  if (!Object.ReferenceEquals(null, writer)) // <- ... And to the check
    writer.Dispose();
}
like image 189
Dmitry Bychenko Avatar answered Sep 21 '22 06:09

Dmitry Bychenko


Is there any difference between these two code samples

Yes, using checks for null before calling Dispose (i.e. the actual code it is expanded to introduces a null check).

why does using exist?

Because the code is more concise. Just a syntactic sugar.

like image 26
ken2k Avatar answered Sep 18 '22 06:09

ken2k