2013-08-05 4 views
7

Ci sono più domande (1, 2, 3, 4 ecc. Ecc.) Chiamato "Perché questa eccezione non viene catturata". Purtroppo, nessuna di queste soluzioni funziona per me ... Quindi sono bloccato da un'eccezione davvero inafferrabile.Moby Dick delle eccezioni

Ho un pezzo di codice (.NET 4.0) che controlla un file di testo di grandi dimensioni per cifre e numeri. Mentre i test ho ricevuto un'eccezione di runtime:

Exception

Quello che vedete qui è un modello di try-catch con un catchblock per un ArgumentOutOfRangeException. Ma durante il runtime, il blocco try lancia una ArgumentOutOfRangeException che non viene catturata.

Ho letto la sezione C# language specification sulla struttura try-catch, e dice:

un blocco catch di un'istruzione try è raggiungibile se l'istruzione try è raggiungibile.

Quindi in teoria il codice di cui sopra dovrebbe catturare l'eccezione.

Quindi ho pensato che potrebbe avere qualcosa a che fare con il fatto che questo codice è in esecuzione in un compito (durante l'elaborazione del file di testo voglio anche aggiornare l'interfaccia utente in modo da farlo asincrono). Ho cercato in giro e poi ho trovato risposta this da Jon Skeet. Sostanzialmente suggerisco di usare Task.Wait in un blocco try-catch per rilevare eventuali eccezioni.

Il problema che sto affrontando ora è che non posso davvero chiamare Task.Attendere perché ciò bloccherebbe il thread chiamante che è il mio thread dell'interfaccia utente! Poi ho pensato che avrei potuto creare un tasklayer in più per aspettare per questo compito:

//Code called from the UI 
System.Threading.Tasks.Task.Factory.StartNew(()=> 
{ 
    //Create a new task and use this task to catch any exceptions 
    System.Threading.Tasks.Task task = System.Threading.Tasks.Task.Factory.StartNew(MethodWithException); 
    try 
    { 
     task.Wait(); 
    } 
    catch(Exception) 
    { 
     MessageBox.Show("Caught it!"); 
    } 
}); 

Ma questo dà ancora lo stesso risultato ... Poi ho pensato che potrebbe essere a causa del fatto che io non sono abbastanza con particolare il mio Exceptiontype. Ma gli stati di specifica linguaggio C#:

Alcuni linguaggi di programmazione possono supportare eccezioni che non sono rappresentabili come un oggetto derivato da System.Exception, sebbene tali eccezioni non potrebbero mai essere generate dal codice C#.

Quindi, a meno che non si utilizzi qualche API di terze parti abbozzata, si è sempre a posto quando si utilizza Exception. Quindi mi sono trovato con una risposta suggerita da Jon Skeet che non ha funzionato per me. In quel momento sapevo che avrei dovuto smettere di provare ...

Quindi qualcuno sa cosa sta succedendo? E come posso risolvere questo? So che potrei semplicemente controllare seè uguale o superiore a text.Length ma capire cosa sta succedendo è più importante del codice di lavoro.

+1

È anche senza un corpo di presa? –

+2

Sei sicuro al 100% che quell'eccezione non sia gestita? È possibile che tu abbia appena impostato l'opzione per interrompere eventuali eccezioni in Visual Studio? – Andrey

+2

Hai provato a eseguire il tuo programma al di fuori dell'IDE VS? – Steve

risposta

7

Questo è semplicemente un artefatto del debugger.

Nel menu Debug, c'è un'opzione chiamata Exceptions... Clic su di esso, e assicurarsi di deselezionare il "gettato" casella qui:

exceptions

Molte volte, ti consigliamo di vedere il errore nel contesto, anche se è all'interno di un try/catch, che è ciò che questa impostazione è per. In questo caso, è esattamente che cosa si dovrebbe fare, in modo da poter vedere confrontare i per la lunghezza di text e vedere dove si trova il problema.

Se si esegue il codice senza il debugger (ad esempio facendo doppio clic sull'eseguibile o utilizzando l'opzione "Avvia senza debug"), si eliminerebbe "correttamente" l'errore senza alcun avviso.

+0

Perché il mio VS non elenca la colonna gestita dall'utente? È perché sto usando la versione Express? – nawfal

+0

Ha funzionato! Grazie! Ma perché non lo fa per ogni eccezione generata? Mi chiedo come è stata selezionata questa casella di controllo perché non è predefinita nei miei altri progetti ... – Jordy

+1

@nawfal - Vedi [questa domanda] (http://stackoverflow.com/questions/2631305/visual-studio-what-happened- to-the-break-quando-un-eccezioni è-gestita-optio). – Bobson

0

ho appena scritto il seguente test:

[TestMethod] 
    public void ArgumentOutOfRangeExceptionTest() 
    { 
     string test = "abc"; 
     int i = 0; 
     try 
     { 
      while (true) 
      { 
       test.ElementAt(i); 
       i++; 
      } 
     } 
     catch (ArgumentOutOfRangeException) 
     { } 
    } 

Si sta lavorando bene. Credo che tu abbia avuto un'altra eccezione, che non è chiamata nel tuo codice chiamante.

Esiste solo un'eccezione che non è possibile rilevare. È lo StackOverflowException. Vedi this question a riguardo.

+0

Penso che 'ExecutingEngineException' non possa essere catturato. – xanatos

+0

L'immagine mostra chiaramente che si è verificata una ArgumentOutOfRangeException. Perché dovresti pensare invece ad una StackOverflowException?La domanda che hai collegato non menziona nulla a riguardo. –

+0

"Credo che tu abbia avuto un'altra eccezione", come può essere diverso da quello che dice lo schermo? O cosa intendi esattamente? – Jordy