The rest of the code inside the Try runs after encountering Exception?

8

The rest of the code within a try is executed after finding a exception or skips directly to the code within catch(Exception e)

try{
  x = 10;
  //alguns erro de try catch
  x = 20;
} catch (Exception e)
{
  x++;
  MessageBox.Show("Valor de x: " + x);
}

In case the message would show 11 or 21?

    
asked by anonymous 17.10.2016 / 13:00

5 answers

10

Short answer:

It will display the value 11. The value 21 would never be displayed because the catch block runs only when there is an exception.

Long answer

Come on, directly from the MSDN

  

When an exception is thrown, the common language runtime (CLR) looks   for the catch statement that handles this exception. If the currently   executing method does not contain such a catch block, the CLR looks at   the method that called the current method, and so on up the call   stack If no catch block is found, then the CLR displays an unhandled   exception message to the user and stops execution of the program.

That is, when an exception is raised, the CLR looks for the closest catch from where this exception was raised and executes its block of code. This means that if the current block of code where the exception was raised does not have a catch , this catch will be searched in the methods that called it until it reaches the top of the call stack, where an exception of type Unhandled Exception for the user, stopping the execution of the program.

Then ...

  

The rest of the code within a try runs after   find an exception or jump directly to the code inside the   catch (Exception e)

The try block contains code that can raise an exception, and it will run while there is no exception or until it is terminated . In other words, if an exception occurs, it will look directly at the nearest catch without executing the rest of the code inside the block try .

  

The try block contains the guarded code that may cause the exception.   The block is executed until an exception is thrown or completed   successfully. For example, the following attempt to cast a null object   raises the NullReferenceException exception:

Why this behavior?

An exception indicates that something unusual occurred during the execution of your code. If "something wrong" occurred during this run, do you want the rest of your code to run normally? The block catch must be used just to execute a specific code for these abnormal cases, when you know they can happen .

The catch block can be used in several ways, as can be seen below:

catch(InvalidOperationException ex)
{
  //Deve ser executado quando uma exceção do tipo InvalidOperationException seja levantada
}
catch(SqlException ex) when (ex.Message.Contains("TIMEOUT"))
{
   //Deve capturar uma exceção do tipo SqlException e que contenha no message a palavra TIMEOUT
}
catch(Exception ex)
{
   //Deve capturar uma exceção que não seja uma InvalidOperationException ou **SqlException que não contenha** no message a palavra TIMEOUT
}

Avoid catching generic (Exception ex) exceptions in your application-specific code unless you know what you're doing (logging at the highest point on the system, for example), or raise it again with a throw or by placing it as a Inner Exception . Finally, there are some exception categories that you can use to guide yourself on your treatment:

  • Usage errors: A usage error represents an error in program logic which may result in an exception. However, this type of error should not be resolved with a block try catch , but with a change in the code to be executed. It's a mistake that you know will happen and which can be avoided .
  • Program error: A runtime error that can not be avoided when building code can fall into this category. Imagine that you need to read a file in a specific directory. In order not to fall into Usage error , you first check if this file exists so you can use it. However, although the check returned true for the existence of the file, at the time of reading it was found unavailable (was deleted or being used by another process) , raising an exception from FileNotFoundException , or similar.
  • System failures: System failures are exceptions that can occur at runtime and can not normally be handled very effectively. What can you as a developer do if a OutOfMemoryException is raised? You can, however, log the information for this exception in a log before the application is terminated for further analysis to prevent this error from occurring again.

Recommended Readings

17.10.2016 / 13:28
4

I've put a complete, verifiable example in dotNetFidle and in TryRoslyn .

Note that the x = 20; line has a warning indicating that it will never run. Of course, if p throw was within a method or something conditional it would not occur. But the example is just in case it is certain that the launch of the exception will be executed. The compiler itself reports that it is guaranteed that the code will not run under that circumstance.

using System;
public class C {
    public static void Main() {
        int x = 0;
        try {
          x = 10;
          throw new Exception();
          x = 20;
        } catch (Exception) {
          x++;
          Console.WriteLine($"Valor de x: {x}");
        }
    }
}

For those with a more advanced knowledge can help to see the IL:

IL_0000: nop
IL_0001: ldc.i4.0
IL_0002: stloc.0
IL_0003: nop
IL_0004: ldc.i4.s 10
IL_0006: stloc.0
IL_0007: newobj instance void [mscorlib]System.Exception::.ctor()
IL_000c: throw
IL_000d: pop
IL_000e: nop
IL_000f: ldloc.0
IL_0010: ldc.i4.1
IL_0011: add
IL_0012: stloc.0
IL_0013: ldstr "Valor de x: {0}"
IL_0018: ldloc.0
IL_0019: box [mscorlib]System.Int32
IL_001e: call string [mscorlib]System.String::Format(string, object)
IL_0023: call void [mscorlib]System.Console::WriteLine(string)
IL_0028: nop
IL_0029: nop
IL_002a: leave.s IL_002c
IL_002c: ret
    
17.10.2016 / 15:15
3

Code execution is interrupted at the time the exception is encountered, so the response is no. The rest of the code below the exception is not executed.

This is one of the goals of the try/catch structure. You can expect some error (exception) that the code can generate and handle properly, without the program crashing and displaying errors on the user's screen.

try{
  x = 10; //Aqui está atribuindo valor 10 a variável x
  // exceção capturada pelo try/catch
  x = 20; // Essa linha não é executada por causa da exception.
} catch (Exception e)
{
  x++; //x está recebendo ele mesmo (10) mais 1;
  MessageBox.Show("Valor de x: " + x);
}

So the printed message would be Valor de x: 11

    
17.10.2016 / 13:17
2

In addition to what has already been said, if you want a block of code to be executed even though an exception is caught, you can include Finally after Catch .

   try 
   {
        // Código a executar
   }
   catch(Exception)
   {
        // Código para tratar a excepção
   }
   Finally
   {
        // Código a executar mesmo que seja accionada uma excepção
        // Exemplo: Fechar um ficheiro que tenha sido aberto pelo System.IO.StreamReader 
   }
    
17.10.2016 / 14:49
1

The value of X will be 11 if the exception is fired between: X = 10 and X = 20.

    
17.10.2016 / 13:15