何时使用try/catch块?

fie*_*ish 35 .net c# exception-handling 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);

    }
}
Run Code Online (Sandbox Code Playgroud)

}

Yuv*_*dam 78

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

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

难道当你在你的代码的特定部分期待一个失败捕获异常,如果你有这方面的后备.

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

  • 在我看来,记录每个异常是一个好主意,只要您在调用堆栈中高位进行并添加一个“ throw”即可。之后发表声明。 (4认同)
  • @Manu - 这并不总是要走的路。想象一下,您是一名系统管理员,您打开一个日志文件却发现数百条无用的痕迹都说“XXX 中的异常”。这对 TCO 有很大影响,通常没有任何好处。登录最合适的位置,以便系统管理员可以使用有意义的跟踪。 (2认同)
  • IIS 保留所有抛出的异常的日志,并且有很多解决方案(即 ELMAH)可以记录所有异常,而不会使您的代码混乱。 (2认同)

Rya*_*ins 9

就像其他人所说的那样,您希望在代码周围使用 try-catch 块,这些代码可以抛出Exception您准备处理的AND 代码。

关于您的特定示例,File.Delete可以抛出许多异常,例如,IOException, UnauthorizedAccessException。在这些情况下,您希望您的应用程序做什么?如果您尝试删除该文件但其他地方的人正在使用它,您将得到一个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
}
Run Code Online (Sandbox Code Playgroud)

另外,请记住,如果这确实失败了,那么File.Moveif接下来在块之外执行的操作也将失败(再次失败IOException- 由于文件没有被删除,它仍然存在,这将导致移动失败)。