2009-11-12 14 views
26

He leído y entiendo lo que hace un bloque Try/Catch y por qué es importante usar uno. Pero estoy atascado en saber when/where para usarlos. ¿Algún consejo? Publicaré una muestra de mi código a continuación con la esperanza de que alguien tenga tiempo para hacer algunas recomendaciones para mi ejemplo.Cuándo usar bloques try/catch?

public AMPFileEntity(string filename) 
    { 
     transferFileList tfl = new transferFileList(); 
     _AMPFlag = tfl.isAMPFile(filename); 
     _requiresPGP = tfl.pgpRequired(filename); 
     _filename = filename.ToUpper(); 
     _fullSourcePathAndFilename = ConfigurationSettings.AppSettings.Get("sourcePath") + _filename; 
     _fullDestinationPathAndFilename = ConfigurationSettings.AppSettings.Get("FTPStagePath") + _filename; 
     _hasBeenPGPdPathAndFilename = ConfigurationSettings.AppSettings.Get("originalsWhichHaveBeenPGPdPath"); 
    } 


    public int processFile() 
    { 

     StringBuilder sb = new StringBuilder(); 
     sb.AppendLine(" "); 
     sb.AppendLine(" --------------------------------"); 
     sb.AppendLine("  Filename: " + _filename); 
     sb.AppendLine("  AMPFlag: " + _AMPFlag); 
     sb.AppendLine("  Requires PGP: " + _requiresPGP); 
     sb.AppendLine(" --------------------------------"); 
     sb.AppendLine(" "); 

     string str = sb.ToString(); 
     UtilityLogger.LogToFile(str); 
     if (_AMPFlag) 
     { 
      if (_requiresPGP == true) 
      { 
       encryptFile(); 
      } 
      else 
      { 
       UtilityLogger.LogToFile("This file does not require encryption. Moving file to FTPStage directory."); 
       if (File.Exists(_fullDestinationPathAndFilename)) 
       { 
        UtilityLogger.LogToFile(_fullDestinationPathAndFilename + " alreadyexists. Archiving that file."); 
        if (File.Exists(_fullDestinationPathAndFilename + "_archive")) 
        { 
         UtilityLogger.LogToFile(_fullDestinationPathAndFilename + "_archive already exists. Overwriting it."); 
         File.Delete(_fullDestinationPathAndFilename + "_archive"); 
        } 
        File.Move(_fullDestinationPathAndFilename, _fullDestinationPathAndFilename + "_archive"); 
       } 
       File.Move(_fullSourcePathAndFilename, _fullDestinationPathAndFilename); 
      } 
     } 
     else 
     { 
      UtilityLogger.LogToFile("This file is not an AMP transfer file. Skipping this file."); 
     } 

      return (0); 
    } 


    private int encryptFile() 
    { 

     UtilityLogger.LogToFile("This file requires encryption. Starting encryption process."); 


     // first check for an existing PGPd file in the destination dir. if exists, archive it - otherwise this one won't save. it doesn't overwrite. 
     string pgpdFilename = _fullDestinationPathAndFilename + ".PGP"; 



     if(File.Exists(pgpdFilename)) 
     { 
      UtilityLogger.LogToFile(pgpdFilename + " already exists in the FTPStage directory. Archiving that file."); 
      if(File.Exists(pgpdFilename + "_archive")) 
      { 
       UtilityLogger.LogToFile(pgpdFilename + "_archive already exists. Overwriting it."); 
       File.Delete(pgpdFilename + "_archive"); 
      } 
      File.Move(pgpdFilename, pgpdFilename + "_archive"); 
     } 

     Process pProc = new Process(); 
     pProc.StartInfo.FileName = "pgp.exe"; 

     string strParams = @"--encrypt " + _fullSourcePathAndFilename + " --recipient infinata --output " + _fullDestinationPathAndFilename + ".PGP"; 

     UtilityLogger.LogToFile("Encrypting file. Params: " + strParams); 
     pProc.StartInfo.Arguments = strParams; 
     pProc.StartInfo.UseShellExecute = false; 
     pProc.StartInfo.RedirectStandardOutput = true; 
     pProc.Start(); 
     pProc.WaitForExit(); 

     //now that it's been PGPd, save the orig in 'hasBeenPGPd' dir 
     UtilityLogger.LogToFile("PGP encryption complete. Moving original unencrypted file to " + _hasBeenPGPdPathAndFilename); 
     if(File.Exists(_hasBeenPGPdPathAndFilename + _filename + "original_which_has_been_pgpd")) 
     { 
      UtilityLogger.LogToFile(_hasBeenPGPdPathAndFilename + _filename + "original_which_has_been_pgpd already exists. Overwriting it."); 
      File.Delete(_hasBeenPGPdPathAndFilename + _filename + "original_which_has_been_pgpd"); 
     } 
      File.Move(_fullSourcePathAndFilename, _hasBeenPGPdPathAndFilename + _filename + "original_which_has_been_pgpd"); 

     return (0); 

    } 
} 

}

+2

Busque aquí 'try catch C#': http://stackoverflow.com/questions/523875/where-to-put-try-catch http://stackoverflow.com/questions/751744/thoughts-on- try-catch-blocks http://stackoverflow.com/questions/505471/how-often-should-i-use-try-and-catch-in-c y entonces no ... – Lazarus

+0

Hay toneladas de preguntas sobre el manejo de excepciones en este sitio! –

+0

Sé que hay un millón de lugares donde podría leer sobre el manejo de excepciones. De hecho, mencioné en mi publicación que entendí el concepto. Estoy atascado en la implementación en este momento y el propósito de mi publicación fue tener la esperanza de que alguien me enseñe cómo aplicarlo a mi circunstancia particular, mi ejemplo de código específico. – fieldingmellish

Respuesta

58

La regla básica para la captura de excepciones es capturar excepciones si y sólo si usted tiene una forma significativa de su manipulación.

No haga tome una excepción si solo va a registrar la excepción y arrojarla a la pila. No sirve ningún significado y desordena el código.

Do detectan una excepción cuando se espera una falla en una parte específica de su código, y si tiene una alternativa para ella.

Por supuesto, siempre tiene el caso de excepciones marcadas que requieren el uso de bloques try/catch, en cuyo caso no tiene otra opción. Incluso con una excepción marcada, asegúrese de iniciar sesión correctamente y de manejar lo más limpiamente posible.

+1

En mi opinión, registrar cada excepción es una buena idea, siempre y cuando lo haga en la parte superior de la pila de llamadas y agregue un "tiro"; declaración justo después. – Manu

+0

@Manu: ese no es siempre el camino a seguir. Imagine que es un administrador de sistema y abre un archivo de registro solo para encontrar cientos de trazas inútiles que dicen "excepción en XXX". Esto tiene un gran impacto en TCO, y generalmente no tiene ningún beneficio. Inicie sesión en el lugar más apropiado para que un administrador de sistema tenga un seguimiento significativo para trabajar. –

+1

IIS mantiene un registro de todas las excepciones lanzadas, y hay muchas soluciones (por ejemplo, ELMAH) que registrarán todas las excepciones sin saturar su código. –

2

Me enseñaron a usar try/catch/finally para cualquier método/clase donde puedan ocurrir múltiples errores y que realmente puede manejar. Transacciones de base de datos, FileSystem I/O, transmisión, etc. La lógica del núcleo generalmente no requiere try/catch/finally.

La mayor parte sobre try/catch/finally es que se pueden tener varias capturas de modo que usted puede crear una serie de controladores de excepciones para hacer frente a error muy específico o utilizar una excepción general para atrapar cualquier error que usted don' veo venir.

En su caso, está utilizando File.Exists, que es bueno, pero su tal vez otro problema con el disco que puede arrojar otro error que File.Exists no puede manejar. Sí, es un método booleano, pero dice que el archivo está bloqueado y ¿qué sucede si intentas escribir en él? Con la captura, puede planear un escenario raro, pero sin try/catch/finally, puede estar exponiendo el código a condiciones completamente imprevistas.

+0

Parte de lo que se dice aquí no es cierto, siempre es útil intentar detectar excepciones para FileIO, por ejemplo, le permite al desarrollador notificar al usuario que, por ejemplo, puede no haber suficiente espacio en la unidad requerida para complete la operación de guardado, o el archivo no existe (si el desarrollador no ha codificado las verificaciones correctamente ... lamentablemente lo que * he * visto). – Paul

+0

@Paul si puede codificarlo como una excepción, también puede codificarlo como un requisito al principio de la función. Entonces, la pregunta no es tanto si debe usar excepciones, pero si no hay otra alternativa. Las excepciones no siempre hacen que el código sea más limpio, ya que está alejando la parte de manejo del error. –

1

Los otros tipos han dado un buen número de buenas referencias y referencias.

Mi entrada es corta:
Cuándo utilizarla es una cosa, igual o más importante es cómo usarla correctamente.

PD: "it" se refiere a "excepciones de prueba".

+0

No podría estar más de acuerdo. – Paul

1

Al igual que algunos otros han dicho, desea utilizar el bloqueo de captura de código que puede arrojar una excepción Y que está preparado para tratar.

Para usted ejemplos particulares, File.Delete puede arrojar una serie de excepciones, incluyendo IOException, UnauthorizedAccessException y otras. ¿Qué quieres que haga tu aplicación en esas situaciones? Si intenta eliminar el archivo pero alguien en otro lugar lo está usando, obtendrá una IOException.

try 
    {  
     File.Delete(pgpdFilename + "_archive") 
    } 
    catch(IOException) 
    { 
     UtilityLogger.LogToFile("File is in use, could not overwrite."); 
     //do something else meaningful to your application 
     //perhaps save it under a different name or something 
    } 

También hay que tener en cuenta que si esto falla, entonces el File.Move que hacer fuera de su si el bloque siguiente también se producirá un error (de nuevo a una IOException - ya que no se ha eliminado el archivo todavía está allí, lo cual hará que la jugada falle).

Cuestiones relacionadas