Когда использовать блоки 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 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);
}
}
}
Ответы
Ответ 1
Основное правило для улавливания исключений - это исключения catch тогда и только тогда, когда у вас есть осмысленный способ их обработки.
Не поймайте исключение, если вы собираетесь регистрировать исключение и бросать его в стек. Он не содержит никакого смысла и не помещает код.
Улавливайте исключение, если ожидаете сбой в определенной части вашего кода, и если у вас есть резерв для него.
Конечно, вы всегда имеете дело с проверенными исключениями, которые требуют использования блоков try/catch, и в этом случае у вас нет другого выбора. Даже с проверенным исключением, убедитесь, что вы правильно записываете и обрабатываете как можно чище.
Ответ 2
Исключения и обработка исключений (Руководство по программированию на С#)
Исключения и обработка исключений (Руководство по программированию на С#)
Обновленная ссылка (по MS), хотя другая все еще актуальна.
Обработка исключений (Руководство по программированию на С#)
Ответ 3
Мне научили использовать try/catch/finally для любых методов/классов, где могут возникать множественные ошибки и которые вы действительно можете обработать. Операции с базами данных, ввода-вывода FileSystem, потоковая передача и т.д. Основная логика обычно не требует try/catch/finally.
Большая часть про try/catch/наконец-то заключается в том, что вы можете иметь несколько уловов, чтобы вы могли создавать серию обработчиков исключений для обработки очень конкретной ошибки или использовать общее исключение, чтобы поймать любые ошибки, которые вы не видите,
В вашем случае вы используете File.Exists, который хорош, но их может быть другая проблема с диском, который может вызвать еще одну ошибку, которую File.Exists не может обработать. Да, это логический метод, но сказать, что файл заблокирован, и что произойдет, если вы попытаетесь написать ему? С уловом вы можете планировать редкий сценарий, но без try/catch/, наконец, вы можете подвергнуть код полностью непредвиденным условиям.
Ответ 4
Другие ребята дали довольно много хороших указателей и ссылок.
Мой ввод короткий:
Когда использовать одно, равно или более важно, как правильно его использовать.
PS: "это" относится к "попыткам исключения".
Ответ 5
Как и некоторые другие, вы хотите использовать блок try catch вокруг кода, который может генерировать исключение и с которым вы готовы справиться.
Для конкретных примеров 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
}
Также имейте в виду, что если это не сработает, то файл File.Move, который вы делаете вне своего блока if, также будет терпеть неудачу (снова к IOException - поскольку файл не был удален, он все еще там, что приведет к перемещению для отказа).