2010-06-09 23 views
16

¿Cómo se puede reanudar la ejecución del código después de que se lanza una excepción?Reanudar la ejecución del código después de que se lanza y atrapa la excepción

Por ejemplo, tomemos el siguiente código:

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) 
      { 
      } 
     } 
    } 
} 

Después de la captura de la excepción al desplazarse por el programa dejará de funcionar. ¿Cómo puedo seguir ejecutando?

EDITAR: Lo que quiero decir específicamente es la línea Console.WriteLine (@class); no parece ser golpeado, porque cuando corro cuando está en modo de depuración, el programa sale del modo de depuración. Quiero correr a esta línea y detenerme en ella.

Gracias

+1

basado en el código anterior, si se produce la excepción del bloque catch apropiado interceptarlo. ¡Cualquier instrucción que venga después del bloque catch será ejecutada! – deostroll

+1

Parece que quieres la versión de C# de BASIC's 'ON ERROR RESUME NEXT'. – Gabe

Respuesta

23

Bueno, no tiene ningún código después de los bloques catch, por lo que el programa dejará de funcionar. No estoy seguro de lo que estás tratando de hacer.

Lo siguiente debe ser una prueba de que el programa no simplemente "se detiene" después de los bloques catch. Será ejecutar código después de que los bloques catch si hay código para ser ejecutado:

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!"); 
} 

El código imprimirá la cadena apropiada en función de la excepción que fue capturado. Luego, imprimirá I am some code that's running after the exception! al final.

ACTUALIZACIÓN

En su edición que preguntó por qué no parece ser golpeado Console.WriteLine(@class);. La razón es que usted es explícitamente lanzando una excepción en la primera línea de su método s(); todo lo que sigue se ignora. Cuando se encuentra una excepción, la ejecución se detiene y la excepción se propaga por la pila de llamadas hasta que el manejador apropiado pueda manejarla (esto puede ser un bloque catch que corresponde al try que envuelve la declaración en cuestión dentro del mismo método, o puede ser un bloque catch más arriba en la pila de llamadas. Si no se encuentra un controlador apropiado, el programa terminará con una pila de rastreo [al menos en Java - no estoy seguro si lo mismo sucede en C#]).

Si desea acceder a la línea Console.WriteLine, no debe lanzar explícitamente una excepción al comienzo del método.

+1

¿Qué pasa con estos downvotes aleatorios drive-by? –

0

ejecución aún está en carying pero no hay código después se detecta la excepción. Si desea llamar repetidamente a s, considere envolver el bloque try/catch en un ciclo while.

0

¡El programa se detiene porque no se ejecuta el siguiente código en el método Main()! Se puede añadir la siguiente línea a su código para mantener el programa en ejecución hasta que haya una entrada de la consola:

Console.ReadLine(); 
0

para ese código, no se puede. Si divide las tareas en trozos más pequeños, puede reanudar en el siguiente trozo. Pero normalmente es más fácil tener un mecanismo diferente a las excepciones para informar errores no fatales, como una función de devolución de llamada que devuelve si continuar o no.

5

Si le preocupa que se envíe una excepción en el método pero desea que el método continúe, agregue un controlador de errores dentro del método.

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(); 
    } 
} 

También podría devolver un bool u otro valor para indicar el estado.

0

Puede utilizar la función "paso a paso" en la depuración para lograr esto en cada ejecución.

3

Descargo de responsabilidad: no estoy sugiriendo que realmente haga esto.

Puede imitar el anterior estilo VB On Error Resume Next con el siguiente código.

public static class ControlFlow 
{ 
    public static Exception ResumeOnError(Action action) 
    { 
    try 
    { 
     action(); 
     return null; 
    } 
    catch (Exception caught) 
    { 
     return caught; 
    } 
    } 
} 

Y luego podría ser utilizado como el siguiente.

public static void Main() 
{ 
    ControlFlow.ResumeOnError(() => { throw new NotSupportedException(); }); 
    ControlFlow.ResumeOnError(() => { Console.WriteLine(); }); 
    ControlFlow.ResumeOnError(() => { Console.ReadLine(); }); 
} 
5

Parece que quiere excepciones reanudables. C# no hace excepciones reanudables, y dudo que CLR las respalde.

El propósito de lanzar una excepción es cancelar una función y una operación completa (pila de llamadas) si/cuando algo en el entorno de llamada (parámetros, estado del objeto, estado global) hace que la operación de la función sea imposible o inválida. Pasar un parámetro cero a una función que necesita dividir una cantidad por ese parámetro, por ejemplo. La división por cero no producirá un resultado significativo, y si ese es el único propósito de la función, entonces la función tampoco puede devolver un resultado significativo. Entonces, lanza una excepción. Esto hará que la ejecución salte a la captura más cercana o finalmente bloquee en la pila de llamadas. No hay retorno a la función que arrojó la excepción.

Si desea ingresar a su código en el depurador para rastrear las llamadas Console.WriteLine(), debe eliminar la nueva línea NotSupportedException() de su código y volver a compilar.

0

Algunos simple código que puse juntos para capturar las excepciones que son arrojados dentro de un bloque catch:

try 
{ 
    //do code here 
} 
catch (Exception ex) 
{ 
    try { SomeMethod1(); } 
    catch { } 

    try { SomeMethod2(); } 
    catch { } 

    try { SomeMethod3(); } 
    catch { } 
} 
finally 
{ 
    //cleanup goes here 
} 
-2
public static void Main() 
{ 
    for (int j = 0; j <= 100000; j++) 
    { 
     try 
     { 
       // TODO: Application logic... 
     } 
     catch 
     { 
       System.Threading.Thread.Sleep(1000); 
     } 
    } 
} 
+1

Simplemente esperará un segundo y luego intentará ejecutarlo nuevamente, siempre que el error haya sido temporal – planninguk

+1

Excepto que su "lógica de aplicación" se repetirá 100000 veces sin importar nada. – CShark

+0

Si bien este código puede responder a la pregunta, proporcionar un contexto adicional con respecto a por qué y/o cómo responde este código a la pregunta mejora su valor a largo plazo. – FirstOne

Cuestiones relacionadas