I am quite confused with how exceptions are getting thrown in C#. If an exception occurs, in the try block,
1.it gets thrown to the catch block,
2. If and only if the catch block catches it the finally block will be executed.
3. The finally block gets executed last, provided the catch statement caught it.
However, when I try to run the program below, the output is A,B not BA.Is there something wrong with my understanding? Thank you.
class Program
{
public static void Main(string[] args)
{
try
{
int a = 2;
int b = 10 / a;
try
{
if (a == 1)
a = a / a - a;
if (a == 2)
{
int[] c = { 1 };
c[8] = 9;
}
}
finally
{
Console.WriteLine("A");
}
}
catch (IndexOutOfRangeException e)
{
Console.WriteLine("B");
}
Console.ReadLine();
}
}
The exception occurs in a==2, and I know the outer catch will catch this exception. However, the finally is being executed first? Any reason as to why this is showing?
edited
From C# docs we know Finally block gets executed whether or not an exception has occured.
However, my finally block never gets executed and in return I am getting a run time error
class Program
{
public static void Main(string[] args)
{
try
{
int a = 2;
int b = 10 / a;
try
{
if (a == 1)
a = a / a - a;
if (a == 2)
{
int[] c = { 1 };
c[8] = 9;
}
}
finally
{
Console.WriteLine("A");
}
}
finally{
Console.WriteLine("finally");
}
Console.ReadLine();
}
}
finally executes when control leaves the try block to which it is attached for any reason; not just if there was a catch block at the same level - that would be a fault handler (in CLR terms) which I think we still cannot do in C#.
So it enters the finally that prints A because control is leaving that try block. It's leaving it because of an exception that's being caught in an outer catch block. That doesn't change any timings/orderings however.
Note that there are some oddities that are possible if the exception is entirely uncaught anywhere in your code. Exception handling happens in two phases. In the first phase, it's trying to locate an appropriate catch clause for the exception, and that can include executing guard clauses (when, C#6 and later). During the second phase, it unwinds the stack and executes any finally clauses as the nesting requires, before reaching the correct level at which the catch clause that will handle the exception is defined1.
I believe that in some environments, if the first phase fails to locate an appropriate exception handler (catch clause) at all, the entire managed environment may be torn down. In such circumstances, the finally clauses aren't executed.
All that is required by a standards conforming CLR is described in the MS Partition I.pdf document, found on ECMA C# and Common Language Infrastructure Standards. Section 12.4.2.5 states:
When an exception occurs, the CLI
searches the array for the first protected block that
Protects a region including the current instruction pointer and
Is a catch handler block and
Whose filter wishes to handle the exception
If a match is not found in the current method, the calling method is searched, and so on. If no match is found
the CLI will dump a stack trace and abort the program.
(My emphasis)
1Illustrated using a variant of Flydog57's example, also C# 7 local functions:
using System;
namespace PlayAreaCSCon
{
internal class Program
{
static void Main(string[] args)
{
TestTryCatchFinally();
Console.WriteLine("Complete");
Console.ReadLine();
}
private static void TestTryCatchFinally()
{
try
{
Console.WriteLine("Start Outer Try");
try
{
Console.WriteLine("Start Inner Try");
throw new Exception("Exception from inner try");
}
finally
{
Console.WriteLine("In Inner Finally");
}
}
catch (Exception ex) when (GuardHelper(ex))
{
Console.WriteLine("In outer catch");
}
finally
{
Console.WriteLine("In outer finally");
}
bool GuardHelper(Exception ex)
{
Console.WriteLine("In outer guard");
return true;
}
}
}
}
This prints:
Start Outer Try
Start Inner Try
In outer guard
In Inner Finally
In outer catch
In outer finally
Complete
Illustrating the two-pass nature of the exception handling (that In outer guard is printed before In Inner Finally)
In your first code, the reason that the finally (A) runs before the catch (B) is because when the exception is thrown, you exit the inner block (causing the finally to run) before the outer block's catch comes into play. Consider this code:
private void TestTryCatchFinally()
{
try
{
Debug.WriteLine("Start Outer Try");
try
{
Debug.WriteLine("Start Inner Try");
throw new Exception("Exception from inner try");
Debug.WriteLine("End of Inner Try - never reaced");
}
//remove this catch block for second test
catch (Exception)
{
Debug.WriteLine("In inner catch");
}
//end of code to remove
finally
{
Debug.WriteLine("In Inner Finally");
}
}
catch (Exception)
{
Debug.WriteLine("In outer catch");
}
finally
{
Debug.WriteLine("In outer finally");
}
}
If I run this code, I get this output:
Start Outer Try
Start Inner Try
Exception thrown: 'System.Exception' in MyTestApp.exe
In inner catch
In Inner Finally
In outer finally
Which is what you expect. But, if I remove the inner catch block (as noted in the code), I get this output:
Start Outer Try
Start Inner Try
Exception thrown: 'System.Exception' in MyTestApp.exe
In Inner Finally
In outer catch
In outer finally
In this case, as soon as execution exits the inner try block, the finally code executes. Then the outer catch block has it's turn.
If you have a single try-catch-finally block, it's true that catch precedes finally. But here, the try-finally and try-catch blocks are being run in order of innermost to outermost. Therefore the finally runs first.
It should look something like this (depents on what you are actually trying to do)
class Program
{
public static void Main(string[] args)
{
try
{
int a = 2;
int b = 10 / a;
if (a == 1)
a = a / a - a;
if (a == 2)
{
int[] c = { 1 };
c[8] = 9;
}
}
catch (IndexOutOfRangeException e)
{
//Do something when something in try block throws error
Console.WriteLine("B");
}
finally
{
//This code will ALWAYS execute
//Even when there is no error, A will be written to console
Console.WriteLine("A");
}
Console.ReadLine();
}
}
I may be missing something. Don't you want the following?
try
{
}
catch (Exception ex)
{
}
finally
{
}
By using a finally{} block, you can ensure that some statements will always run
Related
I couldn't find any Microsoft official resource that shows how code below the finally block execute, the only information in regards to it is the book CLR via C#, the author says:
Code below the finally block executes if no exception is thrown within the try block or if a catch block catches the exception and doesn't throw or re-throw an exception.
Let's say we have the following code:
class Program {
static void Main(string[] args) {
SomeMethod1();
Console.ReadLine();
}
static void SomeMethod1() {
try {
SomeMethod2();
}
finally {
Console.WriteLine("SomeMethod1 finally");
}
Console.WriteLine("SomeMethod1 last");
}
static void SomeMethod2() {
try {
SomeMethod3();
}
catch (DivideByZeroException e) {
Console.WriteLine("SomeMethod2 caught");
}
finally {
Console.WriteLine("SomeMethod2 finally");
}
Console.WriteLine("SomeMethod2 last");
}
static void SomeMethod3() {
try {
SomeMethod4();
}
finally {
Console.WriteLine("SomeMethod3 finally");
}
Console.WriteLine("SomeMethod3 last");
}
static void SomeMethod4() {
try {
Int32 i = 0;
var c = 3 / i;
}
finally {
Console.WriteLine("SomeMethod4 finally");
}
Console.WriteLine("SomeMethod4 last");
}
}
and the output is:
SomeMethod4 finally
SomeMethod3 finally
SomeMethod2 caught
SomeMethod2 finally
SomeMethod2 last
SomeMethod1 finally
SomeMethod1 last
You can see that "SomeMethod4 last" and "SomeMethod3 last" doesn't get printed.
"SomeMethod4 last" doesn't get printed is easy to understand as SomeMethod4 throw an exception and there is no catch block to catch the exception, so it doesn't meet the requirement that specified by the author, fair enough.
But why "SomeMethod3 last" doesn't get printed? there is no exception thrown at SomeMethod3, just like SomeMethod1, so why "SomeMethod1 last" get printed while "SomeMethod3 last" doesn't? Is any Microsoft official resource that explain the mechanics of it?
When the exception is thrown in SomeMethod4, it is flowing up to the calling method which is SomeMethod3. Think of it as if SomeMethod4 was actually inline inside SomeMethod3 like this.
static void SomeMethod3()
{
try
{
try
{
Int32 i = 0;
var c = 3 / i;
}
finally
{
Console.WriteLine("SomeMethod4 finally");
}
Console.WriteLine("SomeMethod4 last");
}
finally
{
Console.WriteLine("SomeMethod3 finally");
}
Console.WriteLine("SomeMethod3 last");
}
The reason SomeMethod2 Last is being run is because it is the part that actually catches the exception.
If you add a catch to SomeMethod3, you will see that SomeMethod3 Last gets printed as well.
Exceptions break the flow of the application, and basically don't stop going back up the call stack until it reaches a catch statement. Technically the exception is being thrown inside SomeMethod1, but its being caught in SomeMethod2 which means the exception never reaches SomeMethod1.
So I'm a student in programming and I want my code to do a try-catch on an exception but ONLY if another exception as not occured. Let me show you want I did:
using (var ctxInsert = new model())
{
CATEGORIES c1 = new CATEGORIES(6, "cat6", "category6");
Console.WriteLine("Please wait while rows are added to tables...");
//first try-catch to know if the new entry exist
try
{
ctxInsert.CATEGORIES.Add(c1);
}
catch (ModelValidationException e1)
{
Console.WriteLine(e1.Message);
Console.WriteLine("Category already exist");
}
//second try-catch to make sure saving changes to table is succesful
try
{
ctxInsert.SaveChanges();
Console.WriteLine(c1.NAME + " : Succesfuly added");
}
catch (DbEntityValidationException e)
{
Console.WriteLine(e.Message);
Console.WriteLine("not done");
}
}
Console.ReadLine();
So what I'm trying to do is that the second try-catch block only runs if the first DIDN'T catch an exception. Cause right now, like this, both try-catch runs and it doesn't make sense to save changes if the first one catches an exception.
I tried a bunch of things on my own but nothing works...
If you need just to make your code working as you expected, you can write like this:
using (var ctxInsert = new model())
{
CATEGORIES c1 = new CATEGORIES(6, "cat6", "category6");
Console.WriteLine("Please wait while rows are added to tables...");
//first try-catch to know if the new entry exist
try
{
ctxInsert.CATEGORIES.Add(c1);
ctxInsert.SaveChanges();
Console.WriteLine(c1.NAME + " : Succesfuly added");
}
catch (ModelValidationException e1)
{
Console.WriteLine(e1.Message);
Console.WriteLine("Category already exist");
}
catch (DbEntityValidationException e)
{
Console.WriteLine(e.Message);
Console.WriteLine("not done");
}
}
Console.ReadLine();
BUT, I'd rather write code without any try/catch but make exception interceptors on top level of your application (There are best practices, depending on what framework you are using)
The whole point of a try-catch is to stop an exception from preventing the rest of your code from executing. In your case, there are a few options I see off the top of my head:
Decide whether a try-catch is really what you're looking for - you could also have your method throw an exception and prevent execution of the rest of the code
Throw an exception in your catch, that way you get your logs and it tells the rest of the code that something went wrong, preventing execution
Use a variable which gets modified by the first catch, then conditionally execute the rest of the code based on that variable
Use a try-catch-finally
yes you can use the finally keyword let me show you with code example
using System;
namespace ErrorHandlingApplication {
class DivNumbers {
int result;
DivNumbers() {
result = 0;
}
public void division(int num1, int num2) {
try {
result = num1 / num2;
} catch (DivideByZeroException e) {
Console.WriteLine("Exception caught: {0}", e);
} finally {
Console.WriteLine("Result: {0}", result);
}
}
static void Main(string[] args) {
DivNumbers d = new DivNumbers();
d.division(25, 0);
Console.ReadKey();
}
}
}
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.
Good day!
i write simple console program. It have func Main () and class Adapter;
some simple code that explains how it works:
void Main()
{
try
{
Work(array);
//subcribing at some events;
Application.Run();
}
catch(Exception ex)
{
//write to log;
}
}
class Adapter
{
....
public void GetSomething()
{
try
{
...some work and exception goes here;
}
catch(Exception ex)
{
//catch exception and do Work:
Work(array);
}
}
}
When exception goes- it catches at GetSomething. So,i write some values.But i need that the program still running after exception.
But after catch in GetSomething method it goes to Exception ex at Main func and program exits;
How to do that program will still running after catch exception in GetSomething method?
Thank you!
If what you want is to catch an exception and continue execution at the point of failure (which might be several layers down in the call stack) and possibly retrying the failed statement, you're pretty much out of luck.
Once your catch clause is invoked, the stack has been unwound up to that point. You can deal with the exception in some way and then choose zero or one of
Continuing the exceptio via throw ;
Re-throwing the exception via throw e;
Throwing a new exception via throw new SomeException();
If didn't choose one of the above, execution continues at the point following the try/catch/finally block. For example:
try
{
DoSomethingThatMightThrowAnException() ;
}
catch ( Exception e )
{
DoSomethingToHandleTheExceptionHere() ;
// Then, choose zero or one of the following:
throw ; // current exception is continue with original stack trace
throw e ; // current exception is re-thrown with new stack trace originating here
throw new Exception() ; // a new exception is thrown with its stack trace originating here
throw new Exception(e) ; // a new exception is thrown as above, with the original exception as the inner exception
}
finally
{
// regardless of whether or not an exception was thrown,
// code in the finally block is always executed after the try
// (and the catch block, if it was invoked)
}
// if you didn't throw, execution continues at this point.
If you don't do one of the above, execution continues at the statement following the try/catch/finally block.
The best you can do as far as retrying is something like this:
// retry operation at most 3
int number_of_retries = 5 ;
for ( int i = 0 ; i < number_of_retries ; ++i )
{
try
{
DoSomethingThatMightThrowAnException() ;
break ; // exit the loop on success
}
catch( Exception e )
{
Log.Error("well...that didn't work") ;
ExecuteRecoveryCode() ;
}
}
This behavior is not possible in .NET. When an exception is thrown, control exits the current point and continues onto the first catch statement it can find in the call stack, or exits the program, thus eliminating execution of the call stack up to that point. This is part of the definition of exceptional behavior.
You can instead break down the process being done by Work and process each item one at a time to enable the same effect as what you're asking. In other words, instead of Work(array), try
foreach(var item in array)
{
try { WorkSingle(item); }
catch { continue; }
}
You can use try, catch and finally:
http://www.dotnetperls.com/finally
http://msdn.microsoft.com/es-es/library/dszsf989.aspx
How is it possible to resume code execution after an exception is thrown?
For example, take the following code:
namespace ConsoleApplication1
{
public class Test
{
public void s()
{
throw new NotSupportedException();
string #class = "" ;
Console.WriteLine(#class);
Console.ReadLine();
}
}
public class Program
{
public static void Main(string[] args)
{
try
{
new Test().s();
}
catch (ArgumentException x)
{
}
catch (Exception ex)
{
}
}
}
}
After catching the exception when stepping through, the program will stop running. How can I still carry on execution?
EDIT: What I specifically mean is the line Console.WriteLine(#class); does not seem to be hit, because when I run to it when in debug mode, the program exits from debug mode. I want to run to this line and stop at it.
Thanks
Well, you don't have any code after the catch blocks, so the program would stop running. Not sure what you're trying to do.
The following should be proof that the program doesn't simply "stop" after the catch blocks. It will execute code after the catch blocks if there is code to be executed:
static void Main(string[] args)
{
try
{
new Test().s();
}
catch (ArgumentException x)
{
Console.WriteLine("ArgumentException caught!");
}
catch (Exception ex)
{
Console.WriteLine("Exception caught!");
}
Console.WriteLine("I am some code that's running after the exception!");
}
The code will print the appropriate string depending on the exception that was caught. Then, it will print I am some code that's running after the exception! at the end.
UPDATE
In your edit you asked why Console.WriteLine(#class); does not seem to be hit. The reason is that you are explicitly throwing an exception in the very first line of your s() method; anything that follows is ignored. When an exception is encountered, execution stops and the exception is propagated up the call stack until the appropriate handler can handle it (this may be a catch block that corresponds to the try that wraps the statement in question within the same method, or it may be a catch block further up the call-stack. If no appropriate handler is found, the program will terminate with a stacktrace [at least in Java - not sure if the same happens in C#]).
If you want to hit the Console.WriteLine line, then you shouldn't be explicitly throwing an exception at the beginning of the method.
It sounds like you're wanting resumeable exceptions. C# doesn't do resumeable exceptions, and I'm doubtful that CLR supports them.
The purpose of throwing an exception is to abort a function and an entire operation (call stack) if/when something in the call environment (parameters, object state, global state) makes the function's operation impossible or invalid. Passing a zero param to a function that needs to divide a quantity by that param, for example. Division by zero won't produce a meaningful result, and if that's the sole purpose of the function, then the function can't return a meaningful result either. So, throw an exception. This will cause execution to jump to the nearest catch or finally block on the call stack. There is no returning to the function that threw the exception.
If you want to step into your code in the debugger to trace the Console.WriteLine() calls, you need to remove the throw new NotSupportedException() line from your code and recompile.
If you're worried that an exception will be thrown in the method but you want the method to continue, add an error handler inside the method.
class Test
{
public void s()
{
try
{
// Code that may throw an exception
throw new NotSupportedException();
}
catch(Exception ex)
{
// Handle the exception - log?, reset some values?
}
string #class = "" ;
Console.WriteLine(#class);
Console.ReadLine();
}
}
You could also return a bool or some other value to indicate the state.
Disclaimer: I am not suggesting that you actually do this.
You can mimic the old VB style On Error Resume Next with the following code.
public static class ControlFlow
{
public static Exception ResumeOnError(Action action)
{
try
{
action();
return null;
}
catch (Exception caught)
{
return caught;
}
}
}
And then it could be used like the following.
public static void Main()
{
ControlFlow.ResumeOnError(() => { throw new NotSupportedException(); });
ControlFlow.ResumeOnError(() => { Console.WriteLine(); });
ControlFlow.ResumeOnError(() => { Console.ReadLine(); });
}
Some simple code I put together to catch exceptions that are thrown inside a catch block:
try
{
//do code here
}
catch (Exception ex)
{
try { SomeMethod1(); }
catch { }
try { SomeMethod2(); }
catch { }
try { SomeMethod3(); }
catch { }
}
finally
{
//cleanup goes here
}
Execution is still carying on but there is no code after the exception is caught. If you want to repeatedly call s then consider wrapping the try/catch block in a while loop.
The program stops running because there is no following code to be executed in the Main() method! You can add the following line to your code to keep the program running until there is a console input:
Console.ReadLine();
For that code, you can't. If you break the tasks up to smaller chunks, you can resume at the next chunk. But normally it's easier to have a different mechanism than exceptions to report non-fatal errors, such as a callback function which returns whether or not to continue.
You can use the "step-over" feature in debugging to achieve this on a per-run basis.
Instead of thowing the NotSupportedException, you could track that an exception was encountered, use a default value, and throw the exception at the end of the method call:
namespace ConsoleApplication1
{
public class Test
{
public void s()
{
bool exceptionEncountered = false;
if(someConditionNotSupported){//stub condition
exceptionEncountered=true
#class="DefaultValue";
}
Console.WriteLine(#class);
Console.ReadLine();
if(exceptionEncountered){
throw new NotSupportedException();
}
}
}
public class Program
{
public static void Main(string[] args)
{
try
{
new Test().s();
}
catch (ArgumentException x)
{
}
catch (Exception ex)
{
}
}
}
}
public static void Main()
{
for (int j = 0; j <= 100000; j++)
{
try
{
// TODO: Application logic...
}
catch
{
System.Threading.Thread.Sleep(1000);
}
}
}