Try, Catch, and Finally are the keywords used for exception handling. There are certain rules as to how we should write all these three blocks together. Usually, a "try" block is followed by "catch" block and "catch" block is followed by "finally" block. Whenever any exception is thrown by the code written inside the "try" block, that exception is handled by the respective "catch" block. However, the execution of "finally" block is little bit different. Irrespective of any exception thrown or not, the "finally" block gets executed unless we abort the system forcibly before the execution. So, this blog will explain the functionality behind the code which makes "finally" block executed by default.
- using System;
- using System.Collections.Generic;
- using System.Linq;
- using System.Text;
- using System.Threading.Tasks;
- namespace ConsoleApplication1 {
- class Program {
- static void Main(string[] args) {
- try {
- var i = 0;
- var j = 10;
- Console.WriteLine(j / i);
- } catch (ArithmeticException ex) {
- Console.WriteLine("Catch block");
- } catch (Exception ex) {
- Console.WriteLine("Catch block");
- // throw new Exception ( "catch" );
- } finally {
- Console.WriteLine("finally block");
- }
- }
- }
- }
Let's know why "finally" block gets executed even though there is no exception. In order to analyze this, I have gone through the IL code for the above code, as given below.
- .method private hidebysig static void Main(string[] args) cil managed {.entrypoint
- // Code size 70 (0x46)
- .maxstack 2.locals init([0] int32 i, [1] int32 j, [2] class[mscorlib] System.ArithmeticException ex, [3] class[mscorlib] System.Exception V_3)
- IL_0000: nop.try {.try {
- IL_0001: nop
- IL_0002: ldc.i4 .0
- IL_0003: stloc .0
- IL_0004: ldc.i4.s 10
- IL_0006: stloc .1
- IL_0007: ldloc .1
- IL_0008: ldloc .0
- IL_0009: div
- IL_000a: call void[mscorlib] System.Console::WriteLine(int32)
- IL_000f: nop
- IL_0010: nop
- IL_0011: leave.s IL_0033
- } // end .try
- catch [mscorlib] System.ArithmeticException {
- IL_0013: stloc .2
- IL_0014: nop
- IL_0015: ldstr "Catch block"
- IL_001a: call void[mscorlib] System.Console::WriteLine(string)
- IL_001f: nop
- IL_0020: nop
- IL_0021: leave.s IL_0033
- } // end handler
- catch [mscorlib] System.Exception {
- IL_0023: stloc .3
- IL_0024: nop
- IL_0025: ldstr "Catch block"
- IL_002a: call void[mscorlib] System.Console::WriteLine(string)
- IL_002f: nop
- IL_0030: nop
- IL_0031: leave.s IL_0033
- } // end handler
- IL_0033: nop
- IL_0034: leave.s IL_0044
- } // end .try
- finally {
- IL_0036: nop
- IL_0037: ldstr "finally block"
- IL_003c: call void[mscorlib] System.Console::WriteLine(string)
- IL_0041: nop
- IL_0042: nop
- IL_0043: endfinally
- } // end handler
- IL_0044: nop
- IL_0045: ret
- } // end of method Program::Main
That’s the reason even though whether we get any exception or not, the "finally" block still gets executed almost all the time.
However, we can skip the execution of "finally" block. We can write "Environment.Exit(0)" inside the "catch" block so that the "finally" block will never get executed.

Vipin PrajapatiPosted Jan 8, 2017, 1:33 AM
clean and free resources that the class was holding onto during the program execution. finally block is optional.
Vipin PrajapatiPosted Jan 8, 2017, 1:32 AM
because , it is good practice to always release resources is the finally block because finally block is guaranteed to execute,irrespective of whether there is an exception or not.
Sinraj VPosted Jan 6, 2017, 1:31 PM
Good one.........................