2010-06-09 6 views
16

Come è possibile riprendere l'esecuzione del codice dopo che è stata generata un'eccezione?Ripresa dell'esecuzione del codice dopo che l'eccezione è stata generata e catturata

Per esempio, prendete il seguente codice:

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

Dopo la cattura l'eccezione quando si passa attraverso, il programma smetterà di funzionare. Come posso portare avanti l'esecuzione?

MODIFICA: Ciò che intendo specificamente è la riga Console.WriteLine (@class); non sembra essere colpito, perché quando corro ad esso quando in modalità di debug, il programma esce dalla modalità di debug. Voglio correre su questa linea e fermarmi a questo.

Grazie

+1

sulla base del codice di cui sopra, se l'eccezione viene generata il blocco catch appropriata intercettarlo. Ogni affermazione che viene dopo il blocco catch verrà eseguita !!! – deostroll

+1

Sembra che tu voglia la versione di BASIC di 'ON ERROR RESUME NEXT'. – Gabe

risposta

23

Bene, non si dispone di alcun codice dopo i blocchi catch, quindi il programma smetterà di funzionare. Non sei sicuro di cosa stai cercando di fare.

Quanto segue dovrebbe essere la prova che il programma non si "ferma" semplicemente dopo i blocchi catch. Sarà eseguire codice dopo che i blocchi catch se c'è codice da eseguire:

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

Il codice stamperà la stringa appropriata a seconda l'eccezione che è stato catturato. Quindi, verrà stampato I am some code that's running after the exception! alla fine.

UPDATE

Nella tua modifica si chiese perché Console.WriteLine(@class); non sembra essere colpito. Il motivo è che tu sei esplicitamente lanciare un'eccezione nella primissima linea del tuo metodo s(); tutto ciò che segue è ignorato. Quando si verifica un'eccezione, l'esecuzione si interrompe e l'eccezione viene propagata nello stack delle chiamate fino a quando il gestore appropriato può gestirlo (può trattarsi di un blocco catch corrispondente allo try che racchiude l'istruzione in questione all'interno dello stesso metodo o potrebbe essere un blocco catch oltre lo stack di chiamata.Se non viene trovato alcun gestore appropriato, il programma terminerà con uno stacktrace [almeno in Java - non è sicuro se lo stesso accade in C#]).

Se si desidera colpire la riga Console.WriteLine, non si dovrebbe generare un'eccezione in modo esplicito all'inizio del metodo.

+1

Che succede con questi downvotes drive-by casuali? –

0

esecuzione è ancora trascinando su, ma non v'è alcun codice dopo l'eccezione e 'colto. Se si desidera chiamare ripetutamente s, prendere in considerazione la possibilità di avvolgere il blocco try/catch in un ciclo while.

0

Il programma si interrompe perché non esiste un codice seguente da eseguire nel metodo Main()! È possibile aggiungere la seguente riga al codice per mantenere il programma in esecuzione fino a quando v'è una console di input:

Console.ReadLine(); 
0

Per questo codice, non si può. Se interrompi le attività fino a pezzi più piccoli, puoi riprendere dal blocco successivo. Ma normalmente è più semplice avere un meccanismo diverso rispetto alle eccezioni per segnalare errori non fatali, come una funzione di callback che restituisce se continuare o meno.

5

Se si è preoccupati che venga generata un'eccezione nel metodo ma si desidera continuare il metodo, aggiungere un gestore di errori all'interno del metodo.

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

È anche possibile restituire un valore bool o qualche altro valore per indicare lo stato.

0

È possibile utilizzare la funzionalità "step-over" nel debug per ottenere questo su base per-run.

3

Disclaimer: Non sto suggerendo che tu lo faccia effettivamente.

È possibile simulare il vecchio stile VB su errore Riprendi Avanti con il seguente codice.

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

E quindi può essere utilizzato come il seguente.

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

Sembra che tu stia desiderando eccezioni riassuntive. C# non fa eccezioni ripubblicabili, e sono dubbioso che CLR le supporti.

Lo scopo di generare un'eccezione è interrompere una funzione e un'intera operazione (stack di chiamate) se/quando qualcosa nell'ambiente di chiamata (parametri, stato dell'oggetto, stato globale) rende l'operazione della funzione impossibile o non valida. Passando un parametro zero a una funzione che ha bisogno di dividere una quantità per quel parametro, ad esempio. La divisione per zero non produrrà un risultato significativo e, se questo è l'unico scopo della funzione, la funzione non può restituire un risultato significativo. Quindi, lancia un'eccezione. Ciò farà sì che l'esecuzione salti al fermo più vicino o alla fine allo stack di chiamata. Non è possibile tornare alla funzione che ha generato l'eccezione.

Se si desidera passare al codice nel debugger per tracciare le chiamate Console.WriteLine(), è necessario rimuovere la nuova riga NotSupportedException() dal codice e ricompilare.

0

Alcuni semplice codice ho messo insieme per intercettare le eccezioni che vengono gettati all'interno di un blocco 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

Attenderà solo un secondo e quindi tenterà di eseguire nuovamente, a condizione che l'errore sia temporaneo. – planninguk

+1

Tranne che la "logica dell'applicazione" verrà ripetuta 100000 volte, a prescindere da cosa. – CShark

+0

Sebbene questo codice possa rispondere alla domanda, fornire un contesto aggiuntivo sul perché e/o su come questo codice risponde alla domanda migliora il suo valore a lungo termine. – FirstOne

Problemi correlati