I know how to use try-catch-finally. However I do not get the advance of using finally as I always can place the code after the try-catch block.
Is there any clear example?
It's almost always used for cleanup, usually implicitly via a using statement:
FileStream stream = new FileStream(...);
try
{
// Read some stuff
}
finally
{
stream.Dispose();
}
Now this is not equivalent to
FileStream stream = new FileStream(...);
// Read some stuff
stream.Dispose();
because the "read some stuff" code could throw an exception or possibly return - and however it completes, we want to dispose of the stream.
So finally blocks are usually for resource cleanup of some kind. However, in C# they're usually implicit via a using statement:
using (FileStream stream = new FileStream(...))
{
// Read some stuff
} // Dispose called automatically
finally blocks are much more common in Java than in C#, precisely because of the using statement. I very rarely write my own finally blocks in C#.
You need a finally because you should not always have a catch:
void M()
{
var fs = new FileStream(...);
try
{
fs.Write(...);
}
finally
{
fs.Close();
}
}
The above method does not catch errors from using fs, leaving them to the caller. But it should always close the stream.
Note that this kind of code would normally use a using() {} block but that is just shorthand for a try/finally. To be complete:
using(var fs = new FileStream(...))
{
fs.Write(...);
} // invisible finally here
try
{
DoSomethingImportant();
}
finally
{
ItIsRidiculouslyImportantThatThisRuns();
}
When you have a finally block, the code therein is guaranteed to run upon exit of the try. If you place code outside of the try/catch, that is not the case. A more common example is the one utilized with disposable resources when you use the using statement.
using (StreamReader reader = new StreamReader(filename))
{
}
expands to
StreamReader reader = null;
try
{
reader = new StreamReader(filename);
// do work
}
finally
{
if (reader != null)
((IDisposable)reader).Dispose();
}
This ensures that all unmanaged resources get disposed and released, even in the case of an exception during the try.
*Note that there are situations when control does not exit the try, and the finally would not actually run. As an easy example, PowerFailureException.
Update: This is actually not a great answer. On the other hand, maybe it is a good answer because it illustrates a perfect example of finally succeeding where a developer (i.e., me) might fail to ensure cleanup properly. In the below code, consider the scenario where an exception other than SpecificException is thrown. Then the first example will still perform cleanup, while the second will not, even though the developer may think "I caught the exception and handled it, so surely the subsequent code will run."
Everybody's giving reasons to use try/finally without a catch. It can still make sense to do so with a catch, even if you're throwing an exception. Consider the case* where you want to return a value.
try
{
DoSomethingTricky();
return true;
}
catch (SpecificException ex)
{
LogException(ex);
return false;
}
finally
{
DoImportantCleanup();
}
The alternative to the above without a finally is (in my opinion) somewhat less readable:
bool success;
try
{
DoSomethingTricky();
success = true;
}
catch (SpecificException ex)
{
LogException(ex);
success = false;
}
DoImportantCleanup();
return success;
*I do think a better example of try/catch/finally is when the exception is re-thrown (using throw, not throw ex—but that's another topic) in the catch block, and so the finally is necessary as without it code after the try/catch would not run. This is typically accomplished with a using statement on an IDisposable resource, but that's not always the case. Sometimes the cleanup is not specifically a Dispose call (or is more than just a Dispose call).
The code put in the finally block is executed even when:
there are return statements in the try or catch block
OR
the catch block rethrows the exception
Example:
public int Foo()
{
try
{
MethodThatCausesException();
}
catch
{
return 0;
}
// this will NOT be executed
ReleaseResources();
}
public int Bar()
{
try
{
MethodThatCausesException();
}
catch
{
return 0;
}
finally
{
// this will be executed
ReleaseResources();
}
}
you don't necessarily use it with exceptions. You may have try/finally to execute some clean up before every return in the block.
The finally block always is executed irrespective of error obtained or not. It is generally used for cleaning up purposes.
For your question, the general use of Catch is to throw the error back to caller, in such cases the code is finally still executes.
The finally block will always be executed even if the exception is re-thrown in the catch block.
If an exception occurs (or is rethrown) in the catch-block, the code after the catch won't be executed - in contrast, code inside a finally will still be executed.
In addition, code inside a finally is even executed when the method is exited using return.
Finally is especially handy when dealing with external resources like files which need to be closed:
Stream file;
try
{
file = File.Open(/**/);
//...
if (someCondition)
return;
//...
}
catch (Exception ex)
{
//Notify the user
}
finally
{
if (file != null)
file.Close();
}
Note however, that in this example you could also use using:
using (Stream file = File.Open(/**/))
{
//Code
}
For example, during the process you may disable WinForm...
try
{
this.Enabled = false;
// some process
}
catch(Exception ex)
{
MessageBox.Show(ex.Message);
}
finally
{
this.Enabled = true;
}
I am not sure how it is done in c#, but in Delphi, you will find "finally" very often. The keyword is manual memory management.
MyObject := TMyObject.Create(); //Constructor
try
//do something
finally
MyObject.Free();
end;
Related
My code is currently
using(var driver = new driver()){something}
And I want to be able to catch exceptions. However I only want to catch exceptions thrown by "driver = new driver". Looking online I can find how to catch exceptions thrown by the whole thing or by "something" but I cannot work out how to put a try-catch into the "using" parameter.
It's a very strange requirement, but whatever that's your call.
You should get rid of the using completely, and handle the dispose yourself (which has the same result).
This is what you want:
driver driver = null;
try
{
try
{
driver = new driver();
}
catch(Exception ex)
{
// Here is your specific exception.
}
// Do something
}
finally
{
if(driver != null)
driver.Dispose();
}
Just do it:
Driver driver = null;
try
{
driver = new Driver();
}
catch()
{
// do whatever, throw, fail, return...
}
// if you did not break out of your logic in the catch (why not?)
// add an if(driver != null) before you proceed
using(driver)
{
// something
}
You can add a method to construct your driver and put your try/catch in there:
private static Driver CreateDriver()
{
try
{
return new Driver();
}
catch(Exception ex)
{
// whatever other exception handling you want
return null;
}
}
using(var driver = CreateDriver())
{
// something
}
Of course, if you do this, when your something code is executing inside the using block, driver may be null, so you'll need to check for this, e.g.:
using(var driver = CreateDriver())
{
if (driver != null)
{
// something
}
}
The "using" clause, primarily function is to dispose managed code resources once the process inside the clause has been completed. It "hides" a try catch block inside it, but if you really want to handle errors, you need to do it yourself.
eg.
Try
{
//do stuff
}
catch (exception ex)
{
//handle exception
//resource.Dispose();
}
After you handle your exceptions, you should dispose the unused resources by calling .Dispose(), assuming that the latter is a managed code resource and encapsulates the IDisposable interface
This question already has answers here:
Why use finally in C#?
(13 answers)
Closed 6 years ago.
I'm teaching myself C# and I am up to studying the try, catch and finally. The book I'm using is discussing how the finally block runs regardless of whether or not the try block is successful. But, wouldn't code that is written outside of the catch block be run anyway even if it wasn't in finally? If so, what's the point of finally? This is the example program the book is providing:
class myAppClass
{
public static void Main()
{
int[] myArray = new int[5];
try
{
for (int ctr = 0; ctr <10; ctr++)
{
myArray[ctr] = ctr;
}
}
catch
{
Console.WriteLine("Exception caught");
}
finally
{
Console.WriteLine("Done with exception handling");
}
Console.WriteLine("End of Program");
Console.ReadLine();
}
}
These are scenarios where a finally is useful:
try
{
//Do something
}
catch (Exception e)
{
//Try to recover from exception
//But if you can't
throw e;
}
finally
{
//clean up
}
Usually you try to recover from exception or handle some types of exceptions, but if you cannot recover of you do not catch a specific type of exception the exception is thrown to the caller, BUT the finally block is executed anyway.
Another situation would be:
try
{
//Do something
return result;
}
finally
{
//clean up
}
If your code runs ok and no exceptions is thrown you can return from the try block and release any resources in the finally block.
In both cases if you put your code outside the try, it will never be executed.
Here is a simple example to show code that is written outside of the catch block does not run anyway even if it wasn't in finally!
try
{
try { throw new Exception(); }
finally { Console.WriteLine("finally"); }
Console.WriteLine("Where am I?");
}
catch { Console.WriteLine("catched"); }
and the output is
finally
catched
Please read the MSDN
The finally block executes code that needs to be run in either case. For example, you frequently rethrow an exception or otherwise go to other code. If the cleanup code for resources is not in a finally block, it will not be executed. You could also put this code in the catch block, but then you would be repeating the code after the try block anyway.
the finally block is incredibly helpful because it allows you to do resource clean up that otherwise wouldn't happen if you hit an exception.
e.g. (in pseudo)
try {
open socket
use socket
}
// note: no catch for any socket exceptions
finally {
delete socket // always executed
}
The whole point of the finally block is to wrap up stuff which you started. Suppose you opened a buffer in the try block, you shall close it in the finally. This is necessary so that even if an exception occurs and you exit from the try the resources are properly closed.
try
{
//Do Something
}
catch
{
//Catch Something
}
finally
{
//Always Do This
}
A lot of times the code inside your catch statement will either rethrow an exception or break out of the current function. If you don't have a finally block, "Always Do this" call won't execute that is if the code inside the catch statement issues a return or throws a new exception.
As I know that Using statement has built in implementation of Dispose() and Try-Catch. So I want to know few things
Is it possible to log an exception inside using statement without
using try-catch block , either inside or outside the statement. If
not, then why its built in to the statement.
Nested or overuse of try-catch is not preferred, then why such model
preferred to use.
using (some_resource)
{
try
{
}
catch
{
}
finally
{
//my exception logging mechanism
}
}
will become
try
{
try
{
}
catch
{
}
finally
{
//my exception logging mechanism
}
}
catch
{
}
finally
{
//some_resource.Dispose()
}
A using statement involves try/finally; there is no catch. But frankly, your concern is overkill; multiply-nested and complex try/catch/finally is "undesirable" because:
it makes the code hard to read
and even harder to get right (most people get it wrong, alas)
it is frequently misused
it suggests your method is doing too much
With using, this isn't an issue; it makes the intent very clean, without adding complexity or concern.
I would just use:
using (some_resource) {
try {
// some code
} catch (Exception ex) {
LogIt(ex);
throw;
}
}
Using compiles to Try{}Finally{}. See the following question: Does a C# using statement perform try/finally?
The reason for this is so that the resource will be disposed of regardless of if an exception is thrown. Resource disposal is the purpose of the using statement.
The correct implementation is:
using(Resource myresource = GetResource())
{
try
{}
catch(Exception e)
{ //Maybe log the exception here when it happens?
}
}
How to correctly let an exception to bubble up?
If I use Try-Catch when calling a method, is just throwing an exception inside a method like not trying to catch it at all?
For illustration: Are these approaches do the same work?
Example 1:
try
{
MyFileHandlingMethod();
}
catch (IOException ex)
{
string recfilepath = "...
string rectoadd = "RecDateTime=" + DateTime.Now.ToString()+ ...+ex.Message.ToString();
File.AppendAllText(recfilepath, rectoadd);
}
catch (exception)
{
throw;
}
...
MyFileHandlingMethod()
{
...
TextReader tr2 = new StreamReader(nfilepath);
resultN = tr2.ReadLine();
tr2.Close();
...
}
Example 2:
try
{
MyFileHandlingMethod();
}
catch (IOException ex)
{
string recfilepath = "...
string rectoadd = "RecDateTime=" + DateTime.Now.ToString()+ ...+ex.Message.ToString();
File.AppendAllText(recfilepath, rectoadd);
}
catch (exception)
{
throw;
}
...
MyFileHandlingMethod()
{
...
try
{
TextReader tr2 = new StreamReader(nfilepath);
resultN = tr2.ReadLine();
tr2.Close();
}
catch (Exception)
{
throw;
}
...
}
Yes, those 2 approaches have almost the same effect; rethrowing will unwind the stack of the exception - meaning the stack frames "below" the method where the throw; will be discarded. They'll still be in the stack trace, but you won't be able to access their local variables in the debugger unless you break on thrown exceptions.
A catch/throw block like the one below where you don't do anything with the exception (like logging), is useless:
catch (Exception)
{
throw;
}
Remove it to clean up, in both your samples. In general, avoid entering a catch block if possible
And your method has another exception related problem, it does not free resources properly. The tr2.Close(); belongs in a finally clause but it's much easier to let the compiler handle that with a using() {} block :
void MyFileHandlingMethod()
{
...
using (TextReader tr2 = new StreamReader(nfilepath))
{
resultN = tr2.ReadLine();
} //tr2.Dispose() inserted automatically here
...
}
First of all you should use the using block with resources as this will take care of closing your resources correctly. The second example is pretty much useless as you don't do any work in the exception handler. Either you should remove it, or wrap it in another Exception to add some information.
Yes, the result is the same.
However, both will result in an unclosed stream if there is an error while reading it. You should use a using block or a try ... finally to make sure that the stream is closed:
using (TextReader tr2 = new StreamReader(nfilepath)) {
resultN = tr2.ReadLine();
}
Note that there is no Close in this code. The using block will dispose the StreamReader, which will close the stream.
The using block is compiled into a try ... finally which it uses to make sure that the StreamReader is always disposed, but the exception will bubble up to the calling method.
I suggest you use your first example, with these changes:
try
{
MyFileHandlingMethod();
}
catch (IOException ex)
{
string recfilepath = "...";
string rectoadd = "RecDateTime=" + DateTime.Now.ToString()+ ex.Message.ToString();
File.AppendAllText(recfilepath, rectoadd);
throw; // rethrow the same exception.
}
// no need for second catch}
You probably want to rethrow the exception once you have logged it, because you are not doing any actual recovery from the error.
Whatever is inside finally blocks is executed (almost) always, so what's the difference between enclosing code into it or leaving it unclosed?
The code inside a finally block will get executed regardless of whether or not there is an exception. This comes in very handy when it comes to certain housekeeping functions you need to always run like closing connections.
Now, I'm guessing your question is why you should do this:
try
{
doSomething();
}
catch
{
catchSomething();
}
finally
{
alwaysDoThis();
}
When you can do this:
try
{
doSomething();
}
catch
{
catchSomething();
}
alwaysDoThis();
The answer is that a lot of times the code inside your catch statement will either rethrow an exception or break out of the current function. With the latter code, the "alwaysDoThis();" call won't execute if the code inside the catch statement issues a return or throws a new exception.
Most advantages of using try-finally have already been pointed out, but I thought I'd add this one:
try
{
// Code here that might throw an exception...
if (arbitraryCondition)
{
return true;
}
// Code here that might throw an exception...
}
finally
{
// Code here gets executed regardless of whether "return true;" was called within the try block (i.e. regardless of the value of arbitraryCondition).
}
This behaviour makes it very useful in various situations, particularly when you need to perform cleanup (dispose resources), though a using block is often better in this case.
Because finally will get executed even if you do not handle an exception in a catch block.
any time you use unmanaged code requests like stream readers, db requests, etc; and you want to catch the exception then use try catch finally and close the stream, data reader, etc. in the finally, if you don't when it errors the connection doesn't get closed, this is really bad with db requests
SqlConnection myConn = new SqlConnection("Connectionstring");
try
{
myConn.Open();
//make na DB Request
}
catch (Exception DBException)
{
//do somehting with exception
}
finally
{
myConn.Close();
myConn.Dispose();
}
if you don't want to catch the error then use
using (SqlConnection myConn = new SqlConnection("Connectionstring"))
{
myConn.Open();
//make na DB Request
myConn.Close();
}
and the connection object will be disposed of automatically if there is an error, but you don't capture the error
Finally statements can execute even after return.
private int myfun()
{
int a = 100; //any number
int b = 0;
try
{
a = (5 / b);
return a;
}
catch (Exception ex)
{
Response.Write(ex.Message);
return a;
}
// Response.Write("Statement after return before finally"); -->this will give error "Syntax error, 'try' expected"
finally
{
Response.Write("Statement after return in finally"); // --> This will execute , even after having return code above
}
Response.Write("Statement after return after finally"); // -->Unreachable code
}
finally, as in:
try {
// do something risky
} catch (Exception ex) {
// handle an exception
} finally {
// do any required cleanup
}
is a guaranteed opportunity to execute code after your try..catch block, regardless of whether or not your try block threw an exception.
That makes it perfect for things like releasing resources, db connections, file handles, etc.
i will explain the use of finally with a file reader exception Example
with out using finally
try{
StreamReader strReader = new StreamReader(#"C:\Ariven\Project\Data.txt");
Console.WriteLine(strReader.ReadeToEnd());
StreamReader.Close();
}
catch (Exception ex)
{
Console.WriteLine(ex.Message);
}
in the above example if the file called Data.txt is missing, an exception will be thrown and will be handled but the statement called StreamReader.Close(); will never be executed.
Because of this resources associated with reader was never released.
To solve the above issue, we use finally
StreamReader strReader = null;
try{
strReader = new StreamReader(#"C:\Ariven\Project\Data.txt");
Console.WriteLine(strReader.ReadeToEnd());
}
catch (Exception ex){
Console.WriteLine(ex.Message);
}
finally{
if (strReader != null){
StreamReader.Close();
}
}
Happy Coding :)
Note:
"#" is used to create a verbatim string, to avoid error of "Unrecognized escape sequence".
The # symbol means to read that string literally, and don't interpret control characters otherwise.
Say you need to set the cursor back to the default pointer instead of a waiting (hourglass) cursor. If an exception is thrown before setting the cursor, and doesn't outright crash the app, you could be left with a confusing cursor.
Sometimes you don't want to handle an exception (no catch block), but you want some cleanup code to execute.
For example:
try
{
// exception (or not)
}
finally
{
// clean up always
}
The finally block is valuable for cleaning up any resources allocated in the try block as well as running any code that must execute even if there is an exception. Control is always passed to the finally block regardless of how the try block exits.
Ahh...I think I see what you're saying! Took me a sec...you're wondering "why place it in the finally block instead of after the finally block and completely outside the try-catch-finally".
As an example, it might be because you are halting execution if you throw an error, but you still want to clean up resources, such as open files, database connections, etc.
Control Flow of the Finally Block is either after the Try or Catch block.
[1. First Code]
[2. Try]
[3. Catch]
[4. Finally]
[5. After Code]
with Exception
1 > 2 > 3 > 4 > 5
if 3 has a Return statement
1 > 2 > 3 > 4
without Exception
1 > 2 > 4 > 5
if 2 has a return statement
1 > 2 > 4
As mentioned in the documentation:
A common usage of catch and finally together is to obtain and use resources in a try block, deal with exceptional circumstances in a catch block, and release the resources in the finally block.
It is also worth reading this, which states:
Once a matching catch clause is found, the system prepares to transfer control to the first statement of the catch clause. Before execution of the catch clause begins, the system first executes, in order, any finally clauses that were associated with try statements more nested that than the one that caught the exception.
So it is clear that code which resides in a finally clause will be executed even if a prior catch clause had a return statement.