2010-11-16 14 views
6

estoy teniendo una gran confusión con el orden de intentar, atrapar y finalmente bloquear la ejecución.orden de ejecución de try catch y finalmente bloque

También quiero saber cuándo debo usar try catch block y qué debo poner en el bloque try catch, también quiero saber si alguna excepción viene en try block, entonces si se toma una acción correspondiente a try block, entonces cuál se ejecuta primero catch o finally (que es siempre para ser ejecutado), y después de la ejecución de estas dos does controla control return to try block o lo abandona para siempre.

+0

Por favor, aprender a utilizar puntos finales ('.') y signos de interrogación ('?') apropiadamente. No puedo entender tu pregunta tal como está actualmente. – BoltClock

Respuesta

6

Si usted tiene (nota: esto no es válida C#, a continuación encontrará un ejemplo válido):

try { 
    // ... some code: A 
} catch(...) { 
    // ... exception code: B 
} finally { 
    // finally code: C 
} 

Código A va a ser ejecutado. Si todo va bien (es decir, no se lanzan excepciones mientras A se está ejecutando), irá a finalmente, por lo que se ejecutará el código C. Si se produce una excepción mientras que A es ejecutado, entonces irá a B y luego, finalmente, a C.

A modo de ejemplo, aquí hay un bloque C# código válido de http://msdn.microsoft.com/en-us/library/dszsf989.aspx:

public class EHClass 
{ 
    void ReadFile(int index) 
    { 
     // To run this code, substitute a valid path from your local machine 
     string path = @"c:\users\public\test.txt"; 
     System.IO.StreamReader file = new System.IO.StreamReader(path); 
     char[] buffer = new char[10]; 
     try 
     { 
      file.ReadBlock(buffer, index, buffer.Length); 
     } 
     catch (System.IO.IOException e) 
     { 
      Console.WriteLine("Error reading from {0}. Message = {1}", path, e.Message); 
     } 
     finally 
     { 
      if (file != null) 
      { 
       file.Close(); 
      } 
     } 
     // Do something with buffer... 
    } 
} 

La razón para utilizar try/catch/finally es evitar que su programa falle si hay algún error en algún código (A en el ejemplo anterior). Si hay un problema, puede usar la parte catch para detectar el problema y hacer algo útil, como informar al usuario, registrar la excepción en un archivo de registro, intentarlo de nuevo o probar algo diferente que suponga que podría funcionar en lugar de intentarlo originalmente.

finally se utiliza para garantizar que se realice una limpieza. P.ej. en A puede tratar de abrir un archivo y leerlo. Si la apertura tiene éxito, pero la lectura falla, tendrá un archivo abierto colgando. Lo que desea en ese caso es cerrarlo, lo que haría en el bloque finally - este bloque siempre se ejecuta, lo que garantiza el cierre del archivo.

Echa un vistazo aquí para obtener más información:

+0

Señor, ¿cuál es el significado de las excepciones que se lanzan en las "condiciones definidas por el usuario"? – NoviceToDotNet

+0

No estoy seguro de entender lo que quiere decir con "condiciones definidas por el usuario"; si se refiere a excepciones definidas por el usuario, consulte aquí: http://msdn.microsoft.com/en-us/library/87cdya3t.aspx. Las excepciones definidas por el usuario se utilizan cuando ninguna de las excepciones definidas por el sistema le da una explicación adecuada del error que desea señalar. –

+0

-1: has informado a los lectores a hacer exactamente lo incorrecto. Si hay un error en el código, entonces el programa ya falló (y también el programador). La mejor idea es permitir que el programa "falle", permitir que los usuarios se quejen de él y luego permitir que el problema se solucione, no ocultar su incompetencia detrás de una cláusula catch e "informar al usuario". –

5

Casi nunca debe usar try/catch.

Solo debe hacer catch excepciones que puede corregir, y solo cuando las está esperando. De lo contrario, permita que la persona que llama maneje la excepción, o no.

Si se usa, cualquier cláusula catch se ejecuta primero, solo una de ellas.

Luego, se ejecuta "finalmente" finally.


Esto se ha expresado mejor en muchos lugares, pero lo intentaré. El siguiente código:

try 
{ 
    // Do something here 
} 
catch (Exception ex) 
{ 
    MessageBox.Show("Friendly error message"); 
} 

no repara la excepción. Oculta la excepción para que el problema nunca se solucione. Ese código no tiene idea de qué excepción fue lanzada, porque las detectará todas, y no hace nada para corregir el problema, simplemente le dice al usuario una ficción educada.

El quid de la cuestión es que el código anterior debe ser sustituido por el siguiente:

// Do something here 

esta manera, si la persona que llama de este método sabe cómo solucionar problemas particulares, entonces la persona que llama puede solucionarlos . No habrá eliminado esa opción de la persona que llama.

Si la persona que llama no sabe cómo solucionar el problema, la persona que llama tampoco debería detectar la excepción.


Aquí hay un ejemplo (de MSDN) sobre el uso razonable de excepciones. Es una forma modificada del ejemplo en la documentación del SmtpFailedRecipientsException Class.

public static void RetryIfBusy(string server) 
{ 
    MailAddress from = new MailAddress("[email protected]"); 
    MailAddress to = new MailAddress("[email protected]"); 
    using (
     MailMessage message = new MailMessage(from, to) 
            { 
             Subject = "Using the SmtpClient class.", 
             Body = 
              @"Using this feature, you can send an e-mail message from an application very easily." 
            }) 
    { 
     message.CC.Add(new MailAddress("[email protected]")); 
     using (SmtpClient client = new SmtpClient(server) {Credentials = CredentialCache.DefaultNetworkCredentials}) 
     { 
      Console.WriteLine("Sending an e-mail message to {0} using the SMTP host {1}.", to.Address, client.Host); 
      try 
      { 
       client.Send(message); 
      } 
      catch (SmtpFailedRecipientsException ex) 
      { 
       foreach (var t in ex.InnerExceptions) 
       { 
        var status = t.StatusCode; 
        if (status == SmtpStatusCode.MailboxBusy || status == SmtpStatusCode.MailboxUnavailable) 
        { 
         Console.WriteLine("Delivery failed - retrying in 5 seconds."); 
         System.Threading.Thread.Sleep(5000); // Use better retry logic than this! 
         client.Send(message); 
        } 
        else 
        { 
         Console.WriteLine("Failed to deliver message to {0}", t.FailedRecipient); 
          // Do something better to log the exception 
        } 
       } 
      } 
      catch (SmtpException ex) 
      { 
       // Here, if you know what to do about particular SMTP status codes, 
       // you can look in ex.StatusCode to decide how to handle this exception 
       // Otherwise, in here, you at least know there was an email problem 
      } 
      // Note that no other, less specific exceptions are caught here, since we don't know 
      // what do do about them 
     } 
    } 
} 

Tenga en cuenta que este código utiliza try/catch para rodear un pequeño fragmento de código. Dentro de ese bloque try/catch, si se lanza una excepción SmtpException o SmtpFailedRecipientsException, sabemos qué hacer al respecto. Si, por ejemplo, tuviéramos que atrapar IOException, no sabríamos lo que significaba o qué hacer al respecto. Cualquier excepción que no sepas cómo corregir no se debe capturar, excepto tal vez para agregar información a la excepción, registrarla y volver a lanzar.

+0

soy más confundido ahora señor, ¿por qué no debería usar try catch block? y si de antemano sé dónde vendrá la excepción, ya lo corregiré. Además, ¿qué significa esta frase? "Deje que la persona que llama maneje la excepción, o no". – NoviceToDotNet

+0

Si no comprende lo que está haciendo, intente escuchar. No lo uses Solo deja las excepciones solo. Si su código arroja una excepción que no debería, entonces corrija su código. Hay muy pocas razones para detectar excepciones, para la mayoría de los desarrolladores. –

4

Un bloque try ... catch se usa para detectar excepciones. En el bloque try, coloque el código que espera que pueda generar una excepción.

Si no se produce una excepción, el código en el bloque try finaliza como se esperaba. Si hay un bloque finally, se ejecutará a continuación.

Si se produce una excepción, la ejecución salta al inicio del primer bloque coincidente catch. Una vez que se completa ese código, se ejecuta el bloque finally (si existe). La ejecución no vuelve al bloque try.

1

Aquí se muestra un ejemplo:

try 
{ 
    someFunctionThatWorks(); 

    functionThatThrowsAnException(); // As soon as this function throws an exception we are taken to the catch block 

    anotherFunction(); // <-- This line will never get executed 
} 
catch(Exception e) 
{ 
    // Here you can handle the exception, if you don't know how to handle it you should not be catching it 
    // After this you will not be taken back to the try block, you will go right to the finally block 
} 
finally 
{ 
    // Code here is always executed at the very end, regardless of whether an exception was thrown or not 
} 
+0

y señor, si finalmente arroja alguna excepción, ¿qué pasará? – NoviceToDotNet

+0

Si se lanza otra excepción en el bloque finally, podría atraparlo anidando otro try ... catch ... finally, de lo contrario actuará como cualquier otra excepción no controlada. Mira este http://stackoverflow.com/questions/481446/throws-exception-in-finally-blocks – tbridge

Cuestiones relacionadas