try catch finally question
Not only will a finally block execute following a catch block, try does not even require that any exception be caught for the finally to execute. The following is perfectly legal code:
try
{
//do stuff
}
finally
{
//clean up
}
I actually took out the catch blocks in some code I inherited when the catch block consisted of:
catch(Exception ex)
{
throw ex;
}
In that case, all that was required was to clean up, so I left it with just a try{} and finally{} block and let exceptions bubble up with their stack trace intact.
What is the purpose of finally in try/catch/finally
In your example, it doesn't make a whole lot of difference.
Picture this, though:
try
{
Console.WriteLine("Executing the try statement.");
throw new NullReferenceException();
}
catch (SomeOtherException e)
{
Console.WriteLine("{0} Caught exception #1.", e);
}
finally
{
Console.WriteLine("Executing finally block.");
}
Console.WriteLine("Executing stuff after try/catch/finally.");
In this case, the catch
won't catch the error, so anything after the whole try/catch/finally will never be reached. However, the finally block will still run.
Exception Handling in c# - try catch finally
In really simple terms, these are what try-catch-finally
blocks do:
Try
The place where you'd put potentially problematic code. If an exception is generated, an exception will be thrown.
Catch
Catch is the ONLY block where an exception will be caught. Hence the name. So when an exception is thrown, if you want to ensure the program doesn't 'hang', you must catch
the exception.
Finally
Do your cleanup. If, say, you have some array in your try
block and you want to clean it up in case of an exception, this is the place to do it.
Try-Finally
The documentation says:
Within a handled exception, the associated finally block is guaranteed to be run. However, if the exception is unhandled, execution of the finally block is dependent on how the exception unwind operation is triggered. That, in turn, is dependent on how your computer is set up.
Meaning, if you don't catch your exception, it depends on the situation whether finally
is run.
So, with that in mind, let's look at your first code block.
static void Main(string[] args)
{
int x = 0;
try
{
int divide = 12 / x;
}
finally
{
Console.WriteLine("I am finally block");
}
Console.ReadLine();
}
You're attempting to do a divide by zero which generates an exception. But there's no place for it to be 'caught', so the program hangs:
So if you add a catch
block here, now it will allow for smooth sailing and go to your finally
as well.
try
{
int divide = 12 / x;
}
catch (Exception ex)
{
Console.WriteLine("Oops. Division by Zero.");
}
finally
{
Console.WriteLine("I am finally block");
}
Now let's take your second code snippet. I'm going to do a small modification and flip the order of two lines of code inside the catch
.
static void Main(string[] args)
{
int x = 0;
try
{
int divide = 12 / x;
}
catch (Exception ex)
{
Console.WriteLine(ex.Message);
int divide = 12 / x;
}
finally
{
Console.WriteLine("I am finally block");
}
Console.ReadLine();
}
Now, the catch
block catches the exception thrown by the first illegal division and prints a message. But then there's a second illegal division inside the catch
, and there's no catch for that thrown exception so the program hangs.
So if you modify it to have a second try-catch
inside the first catch
like so:
static void Main(string[] args)
{
int x = 0;
try
{
int divide = 12 / x;
}
catch (Exception ex)
{
try
{
Console.WriteLine(ex.Message);
int divide = 12 / x;
}
catch (Exception ex2)
{
Console.WriteLine(ex2.Message);
}
}
finally
{
Console.WriteLine("I am finally block");
}
Console.ReadLine();
}
Now it will catch both exceptions and you're good to go.
So the idea is, if you have a try
you should try to have a catch
unless you can justify why you don't want one.
Can I use try-catch-finally like this?
Finally will always be executed, so in this case, it is not its intended purpose, since normal execution would reopen the file a second time. What you intend to do would be achieved in the same (cleaner) way if you do
$s = "";
$c = MyClassForFileHandling::getInstance();
try
{
$s = $c->get_file_content($path);
}
catch(FileNotFoundExeption $e)
{
$c->create_file($path, "text for new file");
$s = $c->get_file_content($path);
}
Then the manual says:
For the benefit of someone anyone who hasn't come across finally blocks before, the key difference between them and normal code following a try/catch block is that they will be executed even the try/catch block would return control to the calling function.
It might do this if:
- code if your try block contains an exception type that you don't catch
- you throw another exception in your catch block
- your try or catch block calls return
Finally would then be useful in this kind of scenario:
function my_get_file_content($path)
{
try
{
return $c->get_file_content($path);
}
catch(FileNotFoundExeption $e)
{
$c->create_file($path, "text for new file");
return $c->get_file_content($path);
}
finally
{
$c->close_file_handler();
}
}
=> if you need to make sure you close your file handler in this case, or some resource in general.
The order of return value with try catch finally
This question is closely related, although it returns literals but not variables: Multiple returns: Which one sets the final return value?
In fun1
the return value is set via return a
in the catch-block. At that line the value of a
is copied into the return value. Changing a
later does not change the return value.
In fun2
you have an explicit return in the finally
block, so the return value in the finally block is what is returned.
Please read carefully through the answers in the question above for why you should not write code like that.
Another related question is this one: Returning from a finally block in Java
Related Topics
Converting Long String of Binary to Hex C#
Imap Auth in Office 365 Using Oauth2
"Do Not Use Abstract Base Class in Design; But in Modeling/Analysis"
How to Convert a String Length to a Pixel Unit
C# MACro Definitions in Preprocessor
How to Add My New User Control to the Toolbox or a New Winform
C# Covariance on Subclass Return Types
How to Register Windows Forms with Simple Injector
Global Setting for Asnotracking()
Wpf Controls Needed to Build Chess Application
No Access to the Session Information Through Signalr Hub. Is My Design Is Wrong
Change Color of Text Within a Winforms Richtextbox
Draw Multiple Freehand Polyline or Curve Drawing - Adding Undo Feature
Does .Net Have a Built-In Eventargs<T>
Check for Any Element That Exists in Two Collections