何时使用try / catch块?

我已完成阅读并了解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); } } 

}

捕获exception的基本经验法则是, 当且仅当您有一种有意义的处理方式时才捕获exception

如果您只是记录exception并将其抛出堆栈,请不要捕获exception。 它没有任何意义和杂乱的代码。

当您预计代码的特定部分出现故障时,如果您有后备备份,请捕获exception。

当然,您总是遇到需要使用try / catch块的已检查exception的情况,在这种情况下您没有其他选择。 即使检查了exception,也要确保正确记录并尽可能干净地处理。

exception和exception处理(C#编程指南)

exception和exception处理(C#编程指南) 更新了链接(通过MS),但另一个仍然是最新的。

exception处理(C#编程指南)

像其他一些人所说的那样,你想在代码中使用try catch块来抛出exception并且你准备好处理它。

对于特定的示例,File.Delete可以抛出许多exception,包括IOException,UnauthorizedAccessException以及其他exception。 在这些情况下,您希望您的应用程序做什么? 如果您尝试删除该文件但其他人正在使用它,您将收到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 } 

还要记住,如果这确实失败了,那么你在if块之外执行的File.Move也将失败(再次发生IOException – 因为文件没有被删除它仍然存在会导致移动失败) 。

我被教导使用try / catch / finally来处理可能发生多个错误并且你可以实际处理的任何方法/类。 数据库事务,FileSystem I / O,流等。核心逻辑通常不需要try / catch / finally。

关于try / catch / finally的最重要的部分是你可以拥有多个catch,这样你就可以创建一系列exception处理程序来处理非常具体的错误,或者使用一般exception来捕获你看不到的任何错误。

在你的情况下,你正在使用File.Exists这是好的,但它们可能是磁盘的另一个问题,可能会抛出File.Exists无法处理的另一个错误。 是的,它是一个布尔方法,但是说文件被锁定了,如果你试着写它会发生什么? 使用catch,您可以计划一个罕见的场景,但是如果没有try / catch / finally,您可能会将代码暴露给完全无法预料的情况。

其他人提供了很多好的指针和参考。

我的意见很简短:
何时使用它是一回事,同样或更重要的是如何正确使用它。

PS:“它”是对“试图捕捉exception”的反思。