На одной из страниц форума https://stackoverflow.com/a/6186400/2948684, где идет обсуждение if/else vs. try/catch
автор ответа все же рекомендует код, который изменяет состояние приложения с помощью внешних источников, обвертывать в блок try/catch
и приводя код
if(File.Exists("file.txt"))
File.Delete("file.txt")
говорит, что даже если выражение File.Exists("file.txt")
вернет true, то перед тем как стек успеет перейти к File.Delete("file.txt")
, что-то может изменить файл извне.
Я удивился, неужели метод File.Exists()
выполняется так медленно. Да я также читал на других страницах, что в случае с File.Exists()
try/catch
быстрее .
И тем не менее, в эти миллисекунды разве может что-то произойти. Да и эти миллисекунды решил подсчитать. К примеру, что на SSD, что на HDD проверка существования файла в корне диска заняла у метода File.Exists()
в среднем 12 миллисекунд. Конечно, если сервер будет обращаться по локалке к отдельному файловому серверу это займет чуть больше, но ведь чуть.
Ну а вопрос мой будет звучать так: если я правильно понял автора, то какой сценарий на практике предполагает возможность такой ситуации? Быть может что-то такое может произойти:
Процесс A
начал переименовывать файла и завис;Процесс Б
выполнил File.Exists()
и вернул true;Процесс A
ожил и переименовал файл;Процесс Б
выполняет File.Delete()
и вернул исключение.Да, именно так.
Об этом пишет Эрик Липперт в одной из лучших своих статей Vexing Exceptions:
Я приведу фрагмент в собственном переводе, а вы обязательно прочтите оригинал.
И наконец, исключения внешнего мира немного похожи на досадные исключения с той разницей, что они не являются результатом ошибок в дизайне. Скорее, они отражают вторжение грубой, неизящной реальности в замечательную, кристально чистую логику вашей программы. Посмотрите на этот C#-псевдокод:
try
{
using ( File f = OpenFile(filename, ForReading) )
{
// что-то делаем
}
}
catch (FileNotFoundException)
{
// обработать ненайденный файл
}
Можно ли избавиться от блока try/catch?
if (!FileExists(filename))
// обработать ненайденный файл
else
using ( File f = ...
Это уже не та же самая программа. Теперь в ней есть «race condition». Какой-то другой процесс мог удалить, залочить, переместить файл, или поменять права доступа между FileExists
и OpenFile
.
Может быть, мы просто недостаточно хитры? Может, можно как-то заблокировать файл? Нет, это не поможет. Носитель может быть удалён пользователем из дисковода, сеть может упасть…
Вы обязаны ловить исключения внешнего мира, потому что они всегда могут произойти, как бы вы не старались их избежать: это события внешнего мира, у вас нет над ними контроля.
Конкретно отвечая на ваш вопрос: проверка существования может быть и быстрой, но удаление файла могло начаться и до начала этой проверки. И закончиться как раз к её концу.
Айфон мало держит заряд, разбираемся с проблемой вместе с AppLab
Перевод документов на английский язык: Важность и ключевые аспекты
Само выражение выглядит как if (bouncers[index] == null)Вопрос, для чего происходит такая проверка?
Недавно задавал такой вопрос на счет списка строк: Поиск строк в массиве по уменьшению их кол-ства
есть программа, которая компилируется в исполняемый файл exe, есть ли методы в C# которые позволяют заглянуть в этот exe? меня интересуют какие...