В этой лекции вы узнаете, как:
Try...Catch ;Catch When ;Err.Number и Err.Description для определения исключений;Try...Catch ;Exit Try.В лекции 8 вы узнали, как распознавать в программах на Microsoft Visual Basic .NET ошибки времени исполнения, и как с помощью инструментов для отладки Microsoft Visual Studio .NET обнаружить в коде программы
Visual Basic .NET включает блок Try...Catch - новую синтаксическую конструкцию для обработки ошибок. В этой лекции вы узнаете, как с помощью блоков кода Try...Catch перехватывать ошибки времени исполнения и как использовать свойства Err.Number и Err.Description для идентификации конкретных ошибок времени исполнения. Вы также узнаете, как для написания более гибких обработчиков ошибок использовать множественные операторы Catch, создавать вложенные блоки кода Try...Catch и использовать оператор Exit Try для досрочного выхода из блока кода Try...Catch. Техники программирования, о которых вы узнаете, аналогичны синтаксису On Error Goto из предыдущих версий Visual Basic, а структурные обработчики ошибок в настоящий момент предоставляются также
Try...Catch - это новый способ написания структурных обработчиков ошибок. Хотя вы можете по-прежнему использовать ключевые слова Visual Basic 6, включая On Error Goto, Resume и Resume Next, запись Try...Catch дает возможность избежать потенциальных сложностей конструкций Goto и предлагает очень эффективный способ управления ошибками времени исполнения.Catch When позволяет проверять конкретные условия программы и обрабатывать в одном блоке кода Try...Catch несколько ошибок времени исполнения.Exit Try предлагает новый способ выхода из структурных обработчиков ошибок.Err.Number и Err.Description для идентификации ошибок времени исполнения. В дополнение к этому можно использовать новый метод Err.GetException, который возвращает информацию об условии возникновения ошибки, которая привела к остановке выполнения программы.Ошибка времени исполнения - или обрушение программы - это неожиданная проблема, возникшая в программе на Visual Basic, после которой она не может продолжать работу. Вы могли видеть обрушение вашей первой программы, если Visual Basic не мог загрузить рисунок из файла, или в предыдущей лекции, когда вы при отладке намеренно внесли в код вашей программы ошибки. Ошибка времени исполнения возникает тогда, когда Visual Basic пытается выполнить оператор, который по какой-то причине не может быть выполнен в том виде, в котором он написан. Это не значит, что Visual Basic не достаточно умен, чтобы справиться с проблемой; это значит, что компилятору Visual Basic не сказали, что делать, если что-то пойдет не так.
К счастью, вы не обязаны мириться со случайными ошибками, которые приводят вашу программу к обрушению. Можно написать специальные процедуры Visual Basic, называемые структурными обработчиками ошибок, которые будут реагировать на ошибки времени исполнения. Обработчик ошибок отслеживает ошибку времени исполнения и говорит программе, как продолжать работу при возникновении этой ошибки. Обработчики ошибок помещаются в процедуры событий, там, где существует возможность возникновения проблемы, или в общие функции или подпрограммы, специально предназначенные для обработки ошибок. (Подробности о написании функций и подпрограмм см. в лекции 10 .) Как предполагает их название, обработчики ошибок обрабатывают ошибку с помощью оператора Try...Catch и специального объекта отслеживания ошибок, который называется Err. У объекта Err есть свойство Number, которое идентифицирует номер ошибки, и свойство Description, в котором содержится описание этой ошибки. Например, если ошибка времени исполнения произошла при загрузке файла с диска, обработчик ошибок может отобразить собственное сообщение об ошибке, которое укажет на проблему, и запретить дисковые операции до тех пор, пока эта проблема не будет устранена пользователем.
Обработчики ошибок можно использовать в любых ситуациях, когда ожидаемое или неожиданное действие может привести к ошибке, которая остановит выполнение программы. Обычно обработчики ошибок используются для обработки внешних событий, которые влияют на программу - например, событий, причиной которых стали неработающая сеть или соединение с интернетом, отсутствующий диск в дисководе для гибких дисков, или отключенный принтер.
Блок кода, используемый для обработки ошибки времени исполнения, называется Try...Catch. Вы помещаете оператор Try в процедуре события непосредственно перед оператором, о котором вы беспокоитесь, а оператор Catch следует непосредственно за ним и содержит операторы, которые вы хотите выполнить, если произойдет ошибка времени исполнения. Также можно использовать некоторые дополнительные операторы, такие, как Catch When, Finally, Exit Try, а также вложенные блоки кода Try...Catch, которые демонстрируется в этой лекции. Базовый синтаксис обработчика исключений Try...Catch показан здесь.
Оператор Try указывает на начало обработчика ошибок
Try Операторы, которые могут вызвать ошибку времени исполнения Catch Операторы, которые выполняются, если ошибка времени исполнения происходит Finally Дополнительные операторы, выполняемые независимо от возникновения ошибки End Try
где Try, Catch и End Try - это обязательные ключевые слова, а Finally и операторы, которые стоят за ним, необязательны. Заметьте, что программисты иногда называют операторы, находящиеся между ключевыми словами Try и Catch защищенным кодом, так как любые ошибки времени исполнения, возникающие в этих операторах, не приведут к обрушению программы. (Вместо этого Visual Basic выполняет операторы обработки ошибок, расположенные в блоке кода Catch.)
В следующем примере продемонстрирована обычная ситуация возникновения ошибки времени исполнения - проблема с путем или дисководом. Чтобы выполнить это упражнение, загрузите пример проекта Visual Basic, который я создал для того, чтобы показать, как графические файлы открываются в объекте вывода изображений на форме Windows. Чтобы подготовиться к этому упражнению, вставьте дискету в дисковод A и скопируйте на него файл Fileopen.bmp. (Копию этого файла, а также проект
Чтобы отобразить процедуру события Button1_Click, дважды щелкните на кнопке Проверить диск формы. Между операторами Private Sub и End Sub вы увидите следующую строку кода программы:
PictureBox1.Image = _
System.Drawing.Bitmap.FromFile ("a:\Fileopen.bmp")
Метод FromFile открывает указанный файл. Здесь он открывает файл Fileopen.bmp, расположенный на диске A, и отображает его в области вывода изображений. Однако если диск вставлен не до конца, или путь к файлу указан неверно, попытка выполнить оператор приведет к возникновению ошибки "File Not Found" (файл не найден). Это и есть та ошибка времени исполнения, которую требуется перехватить.
Оставив дискету в дисководе A, щелкните на кнопке Start (Начать) и запустите программу. Появится форма проекта, показанная ниже.

Щелкните на кнопке Проверить диск формы. Программа загрузит файл Fileopen.bmp с дискеты и отобразит его в области вывода изображений, как показано здесь.

Свойство SizeMode объекта вывода изображений установлено на значение StretchImage, так что файл заполняет все пространство этого объекта. Теперь посмотрите, что происходит, когда дискета в дисководе отсутствует, а программа пытается загрузить файл.
Щелкните на кнопке Проверить диск формы. Программа не может найти файл, и Visual Basic генерирует ошибку времени исполнения - или необработанное исключение, которое приводит к обрушению программы. Откроется следующее диалоговое окно.

Проблема с программой Try...Catch, который распознает эту ошибку и сообщает Visual Basic, что делать при ее возникновении. Теперь вы добавите в программу этот обработчик ошибок.
Button1_Click в Редакторе кода не отображается, отобразите ее. Добавьте в процедуру события, при выполнении которой может возникнуть проблема, обработчик ошибок. На самом деле вы пишете блок кода Try...Catch вокруг кода, являющегося потенциальным источником проблем, чтобы защитить остальную часть программы от возникающих в нем ошибок времени исполнения.Измените процедуру события так, чтобы существующий оператор FromFile оказался между операторами Try и Catch, как показано в следующем блоке кода:
Try
PictureBox1.Image = _
System.Drawing.Bitmap.FromFile ("a:\Fileopen.bmp")
Catch
MsgBox("Пожалуйста, вставьте дискету в дисковод A!")
End Try
Не нужно заново вводить оператор FromFile - просто введите перед ним и после него операторы Try, Catch, MsgBox и End Try. Этот код программы демонстрирует наиболее распространенный способ использования блока кода Try...Catch. Он помещает проблемный оператор FromFile в блок кода Try, и теперь при возникновении ошибки выполняются операторы, находящиеся в блоке кода Catch. Блок кода Catch просто отображает окно сообщения, и просит пользователя вставить требуемый диск в дисковод A, чтобы программа могла продолжать работу. Этот блок кода Try...Catch не содержит оператора Finally, так что обработчик ошибок завершается ключевыми словами End Try.
Щелкните на кнопке Проверить диск. Вместо остановки исполнения программы, Visual Basic вызывает блок кода Catch, который отображает следующее окно сообщения.

Настало время изучить некоторые варианты обработчика ошибок Try...Catch.
Как отмечалось ранее в этой лекции при рассмотрении синтаксиса оператора Try...Catch, в этом операторе можно использовать дополнительный блок Finally. Этот блок исполняет операторы независимо от того, как компилятор выполняет блоки Try или Catch. Другими словами, независимо от того, приводят ли операторы в блоке Try к ошибке времени исполнения, может иметься код, который необходимо выполнить каждый раз по завершении действия обработчика ошибок. Например, можно обновить переменные или свойства, отобразить результаты вычислений в окне сообщения или как-то иначе, выполнить "очистку" переменных или отключение ненужных объектов формы.
В следующем упражнении продемонстрировано, как работает блок Finally, отображающий второе окно сообщения, не зависящее от того, привел ли метод FromFile к ошибке времени исполнения, или нет.
Отобразите процедуру события Button1_Click, а затем отредактируйте блок кода Try...Catch так, чтобы он содержал над оператором End Try дополнительные строки кода. Готовый обработчик ошибок должен выглядеть так.
Try
PictureBox1.Image = _
System.Drawing.Bitmap.FromFile("a:\Fileopen.bmp")
Catch
MsgBox("Пожалуйста, вставьте дискету в дисковод A!")
Finally
MsgBox("Обработка ошибок выполнена")
End Try
Оператор Finally указывает компилятору, что завершающий блок кода должен выполняться независимо от того, обработана ошибка времени исполнения, или нет. Чтобы помочь вам точно разобраться, как это работает, я вставил после оператора Finally функцию MsgBox, которая отображает тестовое сообщение. Хотя это и полезно для тестирования, в реальной программе блок кода Finally можно использовать для обновления значений переменных или свойств, отображения данных или выполнения других операций.
Щелкните на OK. Программа выполнит блок Finally обработчика ошибок, и появится следующее окно сообщения.

Finally, и снова появилось окно сообщения "Обработка ошибок выполнена". Как уже отмечалось, операторы Finally исполняются в конце блока Try...Catch независимо от того, была ли ошибка, или нет.Когда ваши программы станут сложнее, полезно писать более сложные обработчики ошибок Try...Catch, которые будут отслеживать различные ошибки времени исполнения и управлять необычными ситуациями обработки ошибок. Try...Catch поддерживает эту возможность с помощью:
Catch или Finally ;Catch When, который проверяет указанные условия возникновения ошибок;Try...Catch, которые могут быть использованы для создания сложных, но надежных обработчиков ошибок.В дополнение к этому специальный объект обработки ошибок с именем Err позволяет определять и обрабатывать в ваших программах конкретные ошибки времени исполнения. Все эти возможности обработки ошибок обсуждаются в следующем разделе.
Err - это специальный объект Visual Basic, в котором при каждом возникновении ошибки времени исполнения сохраняется подробная информация по этой ошибке. Наиболее полезными из свойств Err для определения ошибок времени исполнения являются Err.Number и Err.Description. Err.Number содержит номер самой последней из ошибок времени исполнения, а Err.Description содержит краткое сообщение об этой ошибке. Совместно используя в обработчике ошибок свойства Err.Number и Err.Description, можно распознавать конкретные ошибки и реагировать на них. Вы можете проинформировать пользователя о том, как себя вести в сложившейся ситуации.
Свойства Err.Number и Err.Description содержат информацию о самой последней ошибке времени исполнения.
Очистить объект Err вы можете с помощью метода Err.Clear (этот метод стирает информацию о предыдущей ошибке). Однако, если вы используете объект Err в блоке Catch, очистка объекта Err обычно необязательна, так как блоки Catch выполняются только при возникновении ошибки времени исполнения в соседнем с ними блоке кода Try.
Следующая таблица содержит перечень большинства ошибок времени исполнения, которые могут возникнуть в приложениях на Visual Basic. За дополнительной информацией по конкретной ошибке обратитесь к справочной системе Visual Studio. В дополнение к этим кодам ошибок, некоторые библиотеки Visual Basic и другие компоненты (такие, как базы данных и системные компоненты) предоставляют свои собственные уникальные сообщения об ошибках, которые часто можно встретить в справочной системе. Заметьте, что, не смотря на описания сообщений об ошибках, некоторые ошибки могут появляться не так, как вы этого ожидаете. Поэтому необходимо по возможности специально проверять номера ошибок, отслеживая изменение свойства Err.Number при выполнении программы. Неиспользуемые номера ошибок в диапазоне 1-1000 зарезервированы за будущим использованием в Visual Basic .NET.
| Нoмер ошибки | Сообщение об ошибке по умолчанию |
|---|---|
| 5 | Procedure call or argument is not valid (Недопустимый вызов процедуры или аргумент) |
| 6 | Overflow (Переполнение) |
| 7 | Out of memory (Недостаточно памяти) |
| 9 | Subscript out of range (Индекс массива выходит за его границы) |
| 11 | Division by zero (Деление на ноль) |
| 13 | |
| 48 | Error in loading DLL (Ошибка при загрузке DLL) |
| 51 | Internal error (Внутренняя ошибка) |
| 52 | Bad File name or number (Неверное имя файла или число) |
| 53 | File not found (Файл не найден) |
| 55 | File already open (Файл уже открыт) |
| 57 | Device I/O error (Ошибка устройства ввода-вывода) |
| 58 | File already exists (Файл уже существует) |
| 61 | Disk full (Диск переполнен) |
| 62 | Input past end of File (Ввод после конца файла) |
| 67 | Too many Files (Слишком много файлов) |
| 68 | Device |
| 70 | |
| 71 | Disk not ready (Диск не готов) |
| 74 | Can't rename with different drive (Не могу переименовать с использованием другого дисковода) |
| 75 | Path/File access error (Ошибка доступа к папке/файлу) |
| 76 | Path not found (Путь не найден) |
| 91 | Object variable or With block variable not set (Не установлены переменная объекта или переменная блока With) |
| 321 | File format is not valid (Недопустимый формат файла) |
| 322 | Cannot create necessary |
| 380 | Property value is not valid (Недопустимое значение свойства) |
| 381 | Property array index is not valid (Недопустимый индекс массива свойств) |
| 422 | Property not found (Свойство не найдено) |
| 423 | Property or method not found (Свойство или метод не найдены) |
| 424 | Object required (Требуется объект) |
| 429 | Cannot create Microsoft ActiveX component (Не могу создать компоненту Microsoft ActiveX) |
| 430 | Class does not support Automation or does not support expected interface (Класс не поддерживает Automation или не поддерживает ожидаемый интерфейс) |
| 438 | Object does not support this property or method (Объект не поддерживает это свойство или метод) |
| 440 | Automation error (Ошибка Automation) |
| 460 | |
| 461 | Method or |
| 462 | The remote server machine does not exist or is |
| 463 | Class not registered on local machine (Класс не зарегистрирован на локальной машине) |
| 481 | Picture is not valid (Недопустимое изображение) |
| 482 | Printer error (Ошибка принтера) |
Следующее упражнение использует для тестирования более чем одного условия ошибки времени исполнения в обработчике ошибок Try...Catch свойства Err.Number и Err.Description. Использование этой функции стало возможным благодаря записи Catch When, которая позволяет проверять в блоке кода Try...Catch конкретные ошибки.
В процедуре события Button1_Click отредактируйте обработчик ошибок Try...Catch в соответствии с показанным ниже блоком кода. (Первоначальный оператор FromFile - тот же, что и в коде, который использовался в предыдущих упражнениях, но операторы Catch изменились.)
Try
PictureBox1.Image = _
System.Drawing.Bitmap.FromFile ("a:\Fileopen.bmp")
Catch When Err.Number = 53 'При ошибке File Not Found (Файл не найден)
MsgBox("Проверьте правильность указания пути к файлу и наличие дискеты")
Catch When Err.Number = 7 'При ошибке Out Of Memory (Недостаточно памяти)
MsgBox("Это действительно точечный рисунок?", , Err.Description)
Catch
MsgBox("Проблема при загрузке файла", , Err.Description)
End Try
Запись Catch When используется в этом обработчике ошибок дважды, и каждый раз она используется со свойством Err.Number и проверяет, сгенерировал ли блок Try конкретный номер ошибки времени исполнения, или нет. Если свойство Err.Number содержит номер 53, это означает, что во время выполнения процедуры открытия файла произошла ошибка времени исполнения File Not Found (Файл не найден), и в окне сообщения отображается сообщение "Проверьте правильность указания пути к файлу и наличие дискеты". Если свойство Err.Number содержит номер 7, то произошла ошибка Out of Memory (Недостаточно памяти) - вероятно, она стала результатом загрузки файла, который не является файлом изображения. (Я получаю эту ошибку, если случайно пытаюсь открыть в объекте вывода изображений с помощью метода FromFile документ Microsoft Word.)
Последний оператор Catch обрабатывает все остальные ошибки времени исполнения, которые потенциально могут возникнуть во время открытия файла - это общий блок "перехвата всего", который выводит в окне сообщения универсальное сообщение об ошибке, а в его строке заголовка выводит сообщение об ошибке, содержащееся в свойстве Err.Description.
Catch When.FromFile измените имя файла Fileopen.bmp на имя файла, который вы только что скопировали на диск A. Использование файла другого формата даст вам возможность протестировать второй тип ошибки времени исполнения - исключение Out of Memory (Недостаточно памяти), которое происходит, когда Visual Basic пытается загрузить файл, не являющийся графическим или содержащим слишком много данных для объекта вывода изображений.Снова запустите программу, а затем щелкните на кнопке Проверить диск. Обработчик ошибок отображает следующее сообщение об ошибке.

FromFile обратно на Fileopen.bmp. Он будет использоваться в следующем упражнении.Оператор Catch When обладает большой мощью. В сочетании со свойствами Err.Number и Err.Description, он позволяет писать сложные обработчики ошибок, которые распознают и реагируют на несколько типов ошибок.
Для тестирования вы можете искусственно сгенерировать в программе ошибки времени исполнения. Эта техника называется выбрасыванием - или генерацией - исключений. Чтобы это сделать, используйте метод Err.Raise с одним из номеров ошибок, приведенных в предыдущей таблице. Например, следующая запись использует метод Raise для создания ошибки времени исполнения Disk Full (Диск переполнен), а затем обрабатывает эту ошибку с помощью оператора Catch When:
Try
Err.Raise(61) ' генерируем ошибку Disk Full (Диск переполнен)
Catch When Err.Number = 61
MsgBox("Ошибка: Диск переполнен")
End Try
Когда вы узнаете, как писать собственные процедуры, эта техника позволит вам генерировать ваши собственные ошибки и возвращать их в вызывающую процедуру.
Еще одна стратегия, которую можно использовать в обработчике ошибок - это попробовать выполнить операцию несколько раз, а затем, если проблема не исчезает, отключить ее. В следующем упражнении блок Try...Catch использует переменную-счетчик с именем Retries для отслеживания количества отображений сообщения "Пожалуйста, вставьте диск в дисковод A!", и после второго раза обработчик ошибок отключает кнопку Проверить диск. Особенность этой методики состоит в объявлении переменной Retries в верхней части кода формы программы так, что ее область видимости будет распространяться на все процедуры событий формы. Затем переменная Retries увеличивается и проверяется в блоке кода Catch. Число попыток может быть изменено простым изменением двойки в операторе, как показано здесь:
If Retries <= 2
В Редакторе кода прокрутите код программы для формы на самый верх, и прямо под тэгом "Windows Form Designer generated code" ("Код, автоматически созданный конструктором форм Windows") введите следующее объявление переменной:
Dim Retries As Short = 0
Retries объявлена как целочисленная переменная типа Short, так как она не может содержать очень большие числа. Ей присваивается начальное значение 0, так что она корректно сбрасывается при каждом запуске программы.
В процедуре события Button1_Click отредактируйте обработчик ошибок Try...Catch так, чтобы он выглядел следующим образом:
Try
PictureBox1.Image = _
System.Drawing.Bitmap.FromFile ("a:\Fileopen.bmp")
Catch
Retries += 1
If Retries <= 2 Then
MsgBox("Пожалуйста, вставьте диск в дисковод A!")
Else
MsgBox("Загрузка файла невозможна")
Button1.Enabled = False
End If
End Try
Блок Try проверяет ту же самую процедуру открытия файла, но на этот раз, если происходит ошибка, блок Catch увеличивает переменную Retries и проверяет ее, чтобы убедиться, что ее значение меньше или равно 2. Чтобы разрешить большее число попыток, число 2 можно изменить - в настоящий момент оно позволяет произойти только двум ошибкам. После того, как произошло две ошибки, выполняется блок Else, и появляется окно сообщения, указывающее, что функция загрузки файла была отключена. Кнопка Проверить диск становится неактивной - рисуется серым цветом и становится недоступной.
Чтобы запустить программу, щелкните на кнопке Start (Начать).
Щелкните на кнопке Проверить диск. Обработчик ошибок отображает в окне сообщения показанное ниже сообщение об ошибке "Пожалуйста, вставьте диск в дисковод A!". За сценой переменная Retries увеличивается и становится равной 1.

Retries устанавливается на значение 2, и снова появляется сообщение "Пожалуйста, вставьте диск в дисковод A!".Щелкните на OK, а затем в третий раз на кнопке Проверить диск. Переменная Retries увеличивается до значения 3, и исполняется блок Else. Появляется показанное здесь сообщение "Загрузка файла невозможна".

Щелкните в окне сообщения на OK. Кнопка Проверить диск формы отключается, как показано ниже.

Обработчик ошибок отследил ошибку при работе с дисководом, позволил пользователю сделать несколько попыток для ее исправления, а затем отключил проблемную кнопку. Это отключающее действие предотвратит будущие ошибки времени исполнения, хотя программа может больше не работать так, как было первоначально задумано.
В обработчиках ошибок также можно использовать вложенный блок кода Try...Catch. Например, если первая попытка прочитать данные с дисковода оказалась неудачной и сгенерировала ошибку времени исполнения, следующий обработчик ошибок использует для единственной повторной попытки выполнения операции второй блок Try...Catch,:
Try
PictureBox1.Image = _
System.Drawing.Bitmap.FromFile ("a:\Fileopen.bmp")
Catch
MsgBox("Вставьте дискету в дисковод A, и нажмите OK!")
Try
PictureBox1.Image = _
System.Drawing.Bitmap.FromFile ("a:\Fileopen.bmp")
Catch
MsgBox("Загрузка файла невозможна")
Button1.Enabled = False
End Try
End Try
Если пользователь после появления сообщения с запросом вставит дискету в дисковод, второй блок Try откроет файл без ошибки. Однако если связанная с файлом ошибка времени исполнения появится снова, второй блок Catch выведет сообщение о том, что загрузка файла теперь невозможна, и отключит кнопку.
В основном, вложенные обработчики ошибок Try...Catch хорошо работают, когда не требуется совершать много повторных попыток. Если требуется выполнить проблемное действие много раз, используйте переменную для подсчета попыток, или разработайте функцию, которая будет содержать обработчик ошибок и которая может быть вызвана из процедур событий много раз. (За дополнительной информацией о создании функций обратитесь к следующей лекции.)
Обработчики ошибок являются не только механизмом для защиты программы от ошибок времени исполнения. Например, следующий код программы, чтобы проверить перед открытием файла его наличие на диске, использует метод File.Exists из пространства имен System.IO библиотеки классов .NET Framework:
If File.Exists("a:\Fileopen.bmp") Then
PictureBox1.Image = _
System.Drawing.Bitmap.FromFile ("a:\Fileopen.bmp")
Else
MsgBox("Не могу найти Fileopen.bmp на диске A.")
End If
Этот оператор If $$\dots$$ Then не является обработчиком ошибок, так как он не предотвращает остановку программы из-за ошибки времени исполнения. Это просто методика проверки, которую некоторые программисты называют защитным программированием. Этот оператор использует удобный метод из библиотеки классов .NET Framework, чтобы проверить возможность выполнения файловой операции, прежде чем на самом деле пытаться ее выполнить. И, в данном конкретном случае, поверка наличия файла с помощью метода .NET Framework работает быстрее, чем ожидание, пока Visual Basic сгенерирует исключение и восстановится после ошибки времени исполнения с помощью обработчика ошибок.
Imports System.IO
За дополнительной информацией об использовании оператора Imports для использования объектов, свойств и методов из библиотек классов .NET Framework обратитесь к лекции 5 .Когда нужно использовать защитные методики программирования, а когда обработчики ошибок? Ответ зависит от того, насколько часто, по вашему мнению, будет возникать проблема с операторами, которые вы планируете использовать. Если исключение или ошибка времени исполнения будет возникать довольно редко, скажем, менее чем в 25% случаев исполнения данного конкретного кода, то использование обработчика ошибок может оказаться наиболее эффективным способом. Обработчики ошибок также более удобны, если у вас более одного проверяемого условия, и если вы хотите предоставить пользователю различные возможности реакции на ошибку. Однако если существует реальная возможность того, что данный кусок кода будет приводить к ошибкам времени исполнения в более чем 25% случаев его исполнения, то обычно защитная методика программирования является наиболее эффективным способом управления. Как уже было сказано при обсуждении блока кода If $$\dots$$ Then, метод File.Exists на самом деле работает быстрее, чем использование обработчика ошибок Try...Catch, так что имеет смысл использовать защитную методику программирования, если большое значение имеет производительность. Наконец, лучше всего использовать в коде комбинацию защитной методики программирования и структурной обработки ошибок.
Прежде чем вы перейдете к следующей лекции, посмотрите на еще один вариант синтаксиса блоков кода Try...Catch, который может быть полезен - оператор Exit Try. Exit Try - это быстрая и простая "грубая" методика преждевременного выхода из блока кода Try...Catch ; если вы уже писали программы на Visual Basic, то вы можете заметить его сходство с операторами Exit For и Exit Sub, которые позволяют раньше времени покидать структурные конструкции. С помощью оператора Exit Try можно полностью покинуть текущий блок кода Try или Catch. Если есть блок кода Finally, то этот код будет выполнен, однако Exit Try позволяет перепрыгнуть через все остальные операторы Try или Catch.
В следующем примере процедуры показано, как работает оператор Exit Try. Сначала он проверяет, установлено ли свойство Enabled объекта PictureBox1 в значение PictureBox1 - это может указывать на то, что область вывода изображений еще не готова к приему данных. Если область вывода еще не доступна, то оператор Exit Try пропускает остальную часть блока кода до конца блока Catch, и попытка загрузки файла не производится.
Try
If PictureBox1.Enabled = False Then Exit Try
PictureBox1.Image = _
System.Drawing.Bitmap.FromFile ("a:\Fileopen.bmp")
Catch
Retries += 1
If Retries <= 2 Then
MsgBox("Пожалуйста, вставьте дискету в дисковод A!")
Else
MsgBox("Загрузка файла невозможна")
Button1.Enabled = False
End If
End Try
Этот пример дополняет последний обработчик ошибок, с которым вы экспериментировали в этой лекции (проект Exit Try в контексте этой программы, снова загрузите проект Exit Try. Вам также потребуется использовать окно Properties (Свойства), чтобы отключить объект вывода изображений в форме (другими словами, установить его свойство Enabled на значение False ).
Поздравляем! Вы изучили много важных базовых методик программирования на Visual Basic .NET и научились писать обработчики ошибок. Теперь вы можно перейти к более сложным вопросам программирования.
| Чтобы | Сделайте следующее |
|---|---|
| Обнаружить и обработать ошибки времени исполнения | Создайте с помощью блоков кода Try $$\dots$$ Catch обработчик ошибок. Например, следующий код обработчика ошибок проверяет проблемы с путем или дисководом: Try
PictureBox1.Image = _
System.Drawing.Bitmap.FromFile _
("a:\fileopen.bmp")
Catch
MsgBox("Проверьте путь или вставьте диск")
Finally
MsgBox("Обработка ошибок завершена")
End Try
|
| Проверить в обработчике события конкретные условия ошибки | Используйте оператор Catch When и свойство Err.Number. Например: Try
PictureBox1.Image = _
System.Drawing.Bitmap.FromFile _
("a:\fileopen.bmp")
Catch When Err.Number = 53 ' если File Not Found
MsgBox("Проверьте путь или вставьте диск")
Catch When Err.Number = 7 ' если Out Of Memory
MsgBox("Это действительно точечный рисунок?", , _
Err.Description)
Catch
MsgBox("Проблема с загрузкой файла", , _
Err.Description)
End Try
|
| Создать в программе собственные ошибки | Используйте метод Err.Raise. Например, следующий код генерирует ошибку Disk Full и обрабатывает ее: Try
Err.Raise(61) ' генерируем ошибку Disk Full
Catch When Err.Number = 61
MsgBox("Ошибка: Диск заполнен")
End Try
|
| Написать вложенные обработчики ошибок Try $$\dots$$ Catch | Поместите один блок кода Try $$\dots$$ Catch внутри другого. Например: Try
PictureBox1.Image = _
System.Drawing.Bitmap.FromFile _
("a:\fileopen.bmp")
Catch
MsgBox("Вставьте диск в дисковод A!")
Try
PictureBox1.Image = _
System.Drawing.Bitmap.FromFile _
("a:\fileopen.bmp")
Catch
MsgBox("Загрузка изображения отключена")
Button1.Enabled = False
End Try
End Try
|
| Выйти из текущего блока кода Try или Catch | Используйте в блоке кода Try или Catch оператор Exit Try. Например: If PictureBox1.Enabled = False Then Exit Try |
В этой лекции вы узнаете, как:
Try...Catch ;Catch When ;Err.Number и Err.Description для определения исключений;Try...Catch ;Exit Try.В лекции 8 вы узнали, как распознавать в программах на Microsoft Visual Basic .NET ошибки времени исполнения, и как с помощью инструментов для отладки Microsoft Visual Studio .NET обнаружить в коде программы
Visual Basic .NET включает блок Try...Catch - новую синтаксическую конструкцию для обработки ошибок. В этой лекции вы узнаете, как с помощью блоков кода Try...Catch перехватывать ошибки времени исполнения и как использовать свойства Err.Number и Err.Description для идентификации конкретных ошибок времени исполнения. Вы также узнаете, как для написания более гибких обработчиков ошибок использовать множественные операторы Catch, создавать вложенные блоки кода Try...Catch и использовать оператор Exit Try для досрочного выхода из блока кода Try...Catch. Техники программирования, о которых вы узнаете, аналогичны синтаксису On Error Goto из предыдущих версий Visual Basic, а структурные обработчики ошибок в настоящий момент предоставляются также
Try...Catch - это новый способ написания структурных обработчиков ошибок. Хотя вы можете по-прежнему использовать ключевые слова Visual Basic 6, включая On Error Goto, Resume и Resume Next, запись Try...Catch дает возможность избежать потенциальных сложностей конструкций Goto и предлагает очень эффективный способ управления ошибками времени исполнения.Catch When позволяет проверять конкретные условия программы и обрабатывать в одном блоке кода Try...Catch несколько ошибок времени исполнения.Exit Try предлагает новый способ выхода из структурных обработчиков ошибок.Err.Number и Err.Description для идентификации ошибок времени исполнения. В дополнение к этому можно использовать новый метод Err.GetException, который возвращает информацию об условии возникновения ошибки, которая привела к остановке выполнения программы.Ошибка времени исполнения - или обрушение программы - это неожиданная проблема, возникшая в программе на Visual Basic, после которой она не может продолжать работу. Вы могли видеть обрушение вашей первой программы, если Visual Basic не мог загрузить рисунок из файла, или в предыдущей лекции, когда вы при отладке намеренно внесли в код вашей программы ошибки. Ошибка времени исполнения возникает тогда, когда Visual Basic пытается выполнить оператор, который по какой-то причине не может быть выполнен в том виде, в котором он написан. Это не значит, что Visual Basic не достаточно умен, чтобы справиться с проблемой; это значит, что компилятору Visual Basic не сказали, что делать, если что-то пойдет не так.
К счастью, вы не обязаны мириться со случайными ошибками, которые приводят вашу программу к обрушению. Можно написать специальные процедуры Visual Basic, называемые структурными обработчиками ошибок, которые будут реагировать на ошибки времени исполнения. Обработчик ошибок отслеживает ошибку времени исполнения и говорит программе, как продолжать работу при возникновении этой ошибки. Обработчики ошибок помещаются в процедуры событий, там, где существует возможность возникновения проблемы, или в общие функции или подпрограммы, специально предназначенные для обработки ошибок. (Подробности о написании функций и подпрограмм см. в лекции 10 .) Как предполагает их название, обработчики ошибок обрабатывают ошибку с помощью оператора Try...Catch и специального объекта отслеживания ошибок, который называется Err. У объекта Err есть свойство Number, которое идентифицирует номер ошибки, и свойство Description, в котором содержится описание этой ошибки. Например, если ошибка времени исполнения произошла при загрузке файла с диска, обработчик ошибок может отобразить собственное сообщение об ошибке, которое укажет на проблему, и запретить дисковые операции до тех пор, пока эта проблема не будет устранена пользователем.
Обработчики ошибок можно использовать в любых ситуациях, когда ожидаемое или неожиданное действие может привести к ошибке, которая остановит выполнение программы. Обычно обработчики ошибок используются для обработки внешних событий, которые влияют на программу - например, событий, причиной которых стали неработающая сеть или соединение с интернетом, отсутствующий диск в дисководе для гибких дисков, или отключенный принтер.
Блок кода, используемый для обработки ошибки времени исполнения, называется Try...Catch. Вы помещаете оператор Try в процедуре события непосредственно перед оператором, о котором вы беспокоитесь, а оператор Catch следует непосредственно за ним и содержит операторы, которые вы хотите выполнить, если произойдет ошибка времени исполнения. Также можно использовать некоторые дополнительные операторы, такие, как Catch When, Finally, Exit Try, а также вложенные блоки кода Try...Catch, которые демонстрируется в этой лекции. Базовый синтаксис обработчика исключений Try...Catch показан здесь.
Оператор Try указывает на начало обработчика ошибок
Try Операторы, которые могут вызвать ошибку времени исполнения Catch Операторы, которые выполняются, если ошибка времени исполнения происходит Finally Дополнительные операторы, выполняемые независимо от возникновения ошибки End Try
где Try, Catch и End Try - это обязательные ключевые слова, а Finally и операторы, которые стоят за ним, необязательны. Заметьте, что программисты иногда называют операторы, находящиеся между ключевыми словами Try и Catch защищенным кодом, так как любые ошибки времени исполнения, возникающие в этих операторах, не приведут к обрушению программы. (Вместо этого Visual Basic выполняет операторы обработки ошибок, расположенные в блоке кода Catch.)
В следующем примере продемонстрирована обычная ситуация возникновения ошибки времени исполнения - проблема с путем или дисководом. Чтобы выполнить это упражнение, загрузите пример проекта Visual Basic, который я создал для того, чтобы показать, как графические файлы открываются в объекте вывода изображений на форме Windows. Чтобы подготовиться к этому упражнению, вставьте дискету в дисковод A и скопируйте на него файл Fileopen.bmp. (Копию этого файла, а также проект
Чтобы отобразить процедуру события Button1_Click, дважды щелкните на кнопке Проверить диск формы. Между операторами Private Sub и End Sub вы увидите следующую строку кода программы:
PictureBox1.Image = _
System.Drawing.Bitmap.FromFile ("a:\Fileopen.bmp")
Метод FromFile открывает указанный файл. Здесь он открывает файл Fileopen.bmp, расположенный на диске A, и отображает его в области вывода изображений. Однако если диск вставлен не до конца, или путь к файлу указан неверно, попытка выполнить оператор приведет к возникновению ошибки "File Not Found" (файл не найден). Это и есть та ошибка времени исполнения, которую требуется перехватить.
Оставив дискету в дисководе A, щелкните на кнопке Start (Начать) и запустите программу. Появится форма проекта, показанная ниже.

Щелкните на кнопке Проверить диск формы. Программа загрузит файл Fileopen.bmp с дискеты и отобразит его в области вывода изображений, как показано здесь.

Свойство SizeMode объекта вывода изображений установлено на значение StretchImage, так что файл заполняет все пространство этого объекта. Теперь посмотрите, что происходит, когда дискета в дисководе отсутствует, а программа пытается загрузить файл.
Щелкните на кнопке Проверить диск формы. Программа не может найти файл, и Visual Basic генерирует ошибку времени исполнения - или необработанное исключение, которое приводит к обрушению программы. Откроется следующее диалоговое окно.

Проблема с программой Try...Catch, который распознает эту ошибку и сообщает Visual Basic, что делать при ее возникновении. Теперь вы добавите в программу этот обработчик ошибок.
Button1_Click в Редакторе кода не отображается, отобразите ее. Добавьте в процедуру события, при выполнении которой может возникнуть проблема, обработчик ошибок. На самом деле вы пишете блок кода Try...Catch вокруг кода, являющегося потенциальным источником проблем, чтобы защитить остальную часть программы от возникающих в нем ошибок времени исполнения.Измените процедуру события так, чтобы существующий оператор FromFile оказался между операторами Try и Catch, как показано в следующем блоке кода:
Try
PictureBox1.Image = _
System.Drawing.Bitmap.FromFile ("a:\Fileopen.bmp")
Catch
MsgBox("Пожалуйста, вставьте дискету в дисковод A!")
End Try
Не нужно заново вводить оператор FromFile - просто введите перед ним и после него операторы Try, Catch, MsgBox и End Try. Этот код программы демонстрирует наиболее распространенный способ использования блока кода Try...Catch. Он помещает проблемный оператор FromFile в блок кода Try, и теперь при возникновении ошибки выполняются операторы, находящиеся в блоке кода Catch. Блок кода Catch просто отображает окно сообщения, и просит пользователя вставить требуемый диск в дисковод A, чтобы программа могла продолжать работу. Этот блок кода Try...Catch не содержит оператора Finally, так что обработчик ошибок завершается ключевыми словами End Try.
Щелкните на кнопке Проверить диск. Вместо остановки исполнения программы, Visual Basic вызывает блок кода Catch, который отображает следующее окно сообщения.

Настало время изучить некоторые варианты обработчика ошибок Try...Catch.
Как отмечалось ранее в этой лекции при рассмотрении синтаксиса оператора Try...Catch, в этом операторе можно использовать дополнительный блок Finally. Этот блок исполняет операторы независимо от того, как компилятор выполняет блоки Try или Catch. Другими словами, независимо от того, приводят ли операторы в блоке Try к ошибке времени исполнения, может иметься код, который необходимо выполнить каждый раз по завершении действия обработчика ошибок. Например, можно обновить переменные или свойства, отобразить результаты вычислений в окне сообщения или как-то иначе, выполнить "очистку" переменных или отключение ненужных объектов формы.
В следующем упражнении продемонстрировано, как работает блок Finally, отображающий второе окно сообщения, не зависящее от того, привел ли метод FromFile к ошибке времени исполнения, или нет.
Отобразите процедуру события Button1_Click, а затем отредактируйте блок кода Try...Catch так, чтобы он содержал над оператором End Try дополнительные строки кода. Готовый обработчик ошибок должен выглядеть так.
Try
PictureBox1.Image = _
System.Drawing.Bitmap.FromFile("a:\Fileopen.bmp")
Catch
MsgBox("Пожалуйста, вставьте дискету в дисковод A!")
Finally
MsgBox("Обработка ошибок выполнена")
End Try
Оператор Finally указывает компилятору, что завершающий блок кода должен выполняться независимо от того, обработана ошибка времени исполнения, или нет. Чтобы помочь вам точно разобраться, как это работает, я вставил после оператора Finally функцию MsgBox, которая отображает тестовое сообщение. Хотя это и полезно для тестирования, в реальной программе блок кода Finally можно использовать для обновления значений переменных или свойств, отображения данных или выполнения других операций.
Щелкните на OK. Программа выполнит блок Finally обработчика ошибок, и появится следующее окно сообщения.

Finally, и снова появилось окно сообщения "Обработка ошибок выполнена". Как уже отмечалось, операторы Finally исполняются в конце блока Try...Catch независимо от того, была ли ошибка, или нет.Когда ваши программы станут сложнее, полезно писать более сложные обработчики ошибок Try...Catch, которые будут отслеживать различные ошибки времени исполнения и управлять необычными ситуациями обработки ошибок. Try...Catch поддерживает эту возможность с помощью:
Catch или Finally ;Catch When, который проверяет указанные условия возникновения ошибок;Try...Catch, которые могут быть использованы для создания сложных, но надежных обработчиков ошибок.В дополнение к этому специальный объект обработки ошибок с именем Err позволяет определять и обрабатывать в ваших программах конкретные ошибки времени исполнения. Все эти возможности обработки ошибок обсуждаются в следующем разделе.
Err - это специальный объект Visual Basic, в котором при каждом возникновении ошибки времени исполнения сохраняется подробная информация по этой ошибке. Наиболее полезными из свойств Err для определения ошибок времени исполнения являются Err.Number и Err.Description. Err.Number содержит номер самой последней из ошибок времени исполнения, а Err.Description содержит краткое сообщение об этой ошибке. Совместно используя в обработчике ошибок свойства Err.Number и Err.Description, можно распознавать конкретные ошибки и реагировать на них. Вы можете проинформировать пользователя о том, как себя вести в сложившейся ситуации.
Свойства Err.Number и Err.Description содержат информацию о самой последней ошибке времени исполнения.
Очистить объект Err вы можете с помощью метода Err.Clear (этот метод стирает информацию о предыдущей ошибке). Однако, если вы используете объект Err в блоке Catch, очистка объекта Err обычно необязательна, так как блоки Catch выполняются только при возникновении ошибки времени исполнения в соседнем с ними блоке кода Try.
Следующая таблица содержит перечень большинства ошибок времени исполнения, которые могут возникнуть в приложениях на Visual Basic. За дополнительной информацией по конкретной ошибке обратитесь к справочной системе Visual Studio. В дополнение к этим кодам ошибок, некоторые библиотеки Visual Basic и другие компоненты (такие, как базы данных и системные компоненты) предоставляют свои собственные уникальные сообщения об ошибках, которые часто можно встретить в справочной системе. Заметьте, что, не смотря на описания сообщений об ошибках, некоторые ошибки могут появляться не так, как вы этого ожидаете. Поэтому необходимо по возможности специально проверять номера ошибок, отслеживая изменение свойства Err.Number при выполнении программы. Неиспользуемые номера ошибок в диапазоне 1-1000 зарезервированы за будущим использованием в Visual Basic .NET.
| Нoмер ошибки | Сообщение об ошибке по умолчанию |
|---|---|
| 5 | Procedure call or argument is not valid (Недопустимый вызов процедуры или аргумент) |
| 6 | Overflow (Переполнение) |
| 7 | Out of memory (Недостаточно памяти) |
| 9 | Subscript out of range (Индекс массива выходит за его границы) |
| 11 | Division by zero (Деление на ноль) |
| 13 | |
| 48 | Error in loading DLL (Ошибка при загрузке DLL) |
| 51 | Internal error (Внутренняя ошибка) |
| 52 | Bad File name or number (Неверное имя файла или число) |
| 53 | File not found (Файл не найден) |
| 55 | File already open (Файл уже открыт) |
| 57 | Device I/O error (Ошибка устройства ввода-вывода) |
| 58 | File already exists (Файл уже существует) |
| 61 | Disk full (Диск переполнен) |
| 62 | Input past end of File (Ввод после конца файла) |
| 67 | Too many Files (Слишком много файлов) |
| 68 | Device |
| 70 | |
| 71 | Disk not ready (Диск не готов) |
| 74 | Can't rename with different drive (Не могу переименовать с использованием другого дисковода) |
| 75 | Path/File access error (Ошибка доступа к папке/файлу) |
| 76 | Path not found (Путь не найден) |
| 91 | Object variable or With block variable not set (Не установлены переменная объекта или переменная блока With) |
| 321 | File format is not valid (Недопустимый формат файла) |
| 322 | Cannot create necessary |
| 380 | Property value is not valid (Недопустимое значение свойства) |
| 381 | Property array index is not valid (Недопустимый индекс массива свойств) |
| 422 | Property not found (Свойство не найдено) |
| 423 | Property or method not found (Свойство или метод не найдены) |
| 424 | Object required (Требуется объект) |
| 429 | Cannot create Microsoft ActiveX component (Не могу создать компоненту Microsoft ActiveX) |
| 430 | Class does not support Automation or does not support expected interface (Класс не поддерживает Automation или не поддерживает ожидаемый интерфейс) |
| 438 | Object does not support this property or method (Объект не поддерживает это свойство или метод) |
| 440 | Automation error (Ошибка Automation) |
| 460 | |
| 461 | Method or |
| 462 | The remote server machine does not exist or is |
| 463 | Class not registered on local machine (Класс не зарегистрирован на локальной машине) |
| 481 | Picture is not valid (Недопустимое изображение) |
| 482 | Printer error (Ошибка принтера) |
Следующее упражнение использует для тестирования более чем одного условия ошибки времени исполнения в обработчике ошибок Try...Catch свойства Err.Number и Err.Description. Использование этой функции стало возможным благодаря записи Catch When, которая позволяет проверять в блоке кода Try...Catch конкретные ошибки.
В процедуре события Button1_Click отредактируйте обработчик ошибок Try...Catch в соответствии с показанным ниже блоком кода. (Первоначальный оператор FromFile - тот же, что и в коде, который использовался в предыдущих упражнениях, но операторы Catch изменились.)
Try
PictureBox1.Image = _
System.Drawing.Bitmap.FromFile ("a:\Fileopen.bmp")
Catch When Err.Number = 53 'При ошибке File Not Found (Файл не найден)
MsgBox("Проверьте правильность указания пути к файлу и наличие дискеты")
Catch When Err.Number = 7 'При ошибке Out Of Memory (Недостаточно памяти)
MsgBox("Это действительно точечный рисунок?", , Err.Description)
Catch
MsgBox("Проблема при загрузке файла", , Err.Description)
End Try
Запись Catch When используется в этом обработчике ошибок дважды, и каждый раз она используется со свойством Err.Number и проверяет, сгенерировал ли блок Try конкретный номер ошибки времени исполнения, или нет. Если свойство Err.Number содержит номер 53, это означает, что во время выполнения процедуры открытия файла произошла ошибка времени исполнения File Not Found (Файл не найден), и в окне сообщения отображается сообщение "Проверьте правильность указания пути к файлу и наличие дискеты". Если свойство Err.Number содержит номер 7, то произошла ошибка Out of Memory (Недостаточно памяти) - вероятно, она стала результатом загрузки файла, который не является файлом изображения. (Я получаю эту ошибку, если случайно пытаюсь открыть в объекте вывода изображений с помощью метода FromFile документ Microsoft Word.)
Последний оператор Catch обрабатывает все остальные ошибки времени исполнения, которые потенциально могут возникнуть во время открытия файла - это общий блок "перехвата всего", который выводит в окне сообщения универсальное сообщение об ошибке, а в его строке заголовка выводит сообщение об ошибке, содержащееся в свойстве Err.Description.
Catch When.FromFile измените имя файла Fileopen.bmp на имя файла, который вы только что скопировали на диск A. Использование файла другого формата даст вам возможность протестировать второй тип ошибки времени исполнения - исключение Out of Memory (Недостаточно памяти), которое происходит, когда Visual Basic пытается загрузить файл, не являющийся графическим или содержащим слишком много данных для объекта вывода изображений.Снова запустите программу, а затем щелкните на кнопке Проверить диск. Обработчик ошибок отображает следующее сообщение об ошибке.

FromFile обратно на Fileopen.bmp. Он будет использоваться в следующем упражнении.Оператор Catch When обладает большой мощью. В сочетании со свойствами Err.Number и Err.Description, он позволяет писать сложные обработчики ошибок, которые распознают и реагируют на несколько типов ошибок.
Для тестирования вы можете искусственно сгенерировать в программе ошибки времени исполнения. Эта техника называется выбрасыванием - или генерацией - исключений. Чтобы это сделать, используйте метод Err.Raise с одним из номеров ошибок, приведенных в предыдущей таблице. Например, следующая запись использует метод Raise для создания ошибки времени исполнения Disk Full (Диск переполнен), а затем обрабатывает эту ошибку с помощью оператора Catch When:
Try
Err.Raise(61) ' генерируем ошибку Disk Full (Диск переполнен)
Catch When Err.Number = 61
MsgBox("Ошибка: Диск переполнен")
End Try
Когда вы узнаете, как писать собственные процедуры, эта техника позволит вам генерировать ваши собственные ошибки и возвращать их в вызывающую процедуру.
Еще одна стратегия, которую можно использовать в обработчике ошибок - это попробовать выполнить операцию несколько раз, а затем, если проблема не исчезает, отключить ее. В следующем упражнении блок Try...Catch использует переменную-счетчик с именем Retries для отслеживания количества отображений сообщения "Пожалуйста, вставьте диск в дисковод A!", и после второго раза обработчик ошибок отключает кнопку Проверить диск. Особенность этой методики состоит в объявлении переменной Retries в верхней части кода формы программы так, что ее область видимости будет распространяться на все процедуры событий формы. Затем переменная Retries увеличивается и проверяется в блоке кода Catch. Число попыток может быть изменено простым изменением двойки в операторе, как показано здесь:
If Retries <= 2
В Редакторе кода прокрутите код программы для формы на самый верх, и прямо под тэгом "Windows Form Designer generated code" ("Код, автоматически созданный конструктором форм Windows") введите следующее объявление переменной:
Dim Retries As Short = 0
Retries объявлена как целочисленная переменная типа Short, так как она не может содержать очень большие числа. Ей присваивается начальное значение 0, так что она корректно сбрасывается при каждом запуске программы.
В процедуре события Button1_Click отредактируйте обработчик ошибок Try...Catch так, чтобы он выглядел следующим образом:
Try
PictureBox1.Image = _
System.Drawing.Bitmap.FromFile ("a:\Fileopen.bmp")
Catch
Retries += 1
If Retries <= 2 Then
MsgBox("Пожалуйста, вставьте диск в дисковод A!")
Else
MsgBox("Загрузка файла невозможна")
Button1.Enabled = False
End If
End Try
Блок Try проверяет ту же самую процедуру открытия файла, но на этот раз, если происходит ошибка, блок Catch увеличивает переменную Retries и проверяет ее, чтобы убедиться, что ее значение меньше или равно 2. Чтобы разрешить большее число попыток, число 2 можно изменить - в настоящий момент оно позволяет произойти только двум ошибкам. После того, как произошло две ошибки, выполняется блок Else, и появляется окно сообщения, указывающее, что функция загрузки файла была отключена. Кнопка Проверить диск становится неактивной - рисуется серым цветом и становится недоступной.
Чтобы запустить программу, щелкните на кнопке Start (Начать).
Щелкните на кнопке Проверить диск. Обработчик ошибок отображает в окне сообщения показанное ниже сообщение об ошибке "Пожалуйста, вставьте диск в дисковод A!". За сценой переменная Retries увеличивается и становится равной 1.

Retries устанавливается на значение 2, и снова появляется сообщение "Пожалуйста, вставьте диск в дисковод A!".Щелкните на OK, а затем в третий раз на кнопке Проверить диск. Переменная Retries увеличивается до значения 3, и исполняется блок Else. Появляется показанное здесь сообщение "Загрузка файла невозможна".

Щелкните в окне сообщения на OK. Кнопка Проверить диск формы отключается, как показано ниже.

Обработчик ошибок отследил ошибку при работе с дисководом, позволил пользователю сделать несколько попыток для ее исправления, а затем отключил проблемную кнопку. Это отключающее действие предотвратит будущие ошибки времени исполнения, хотя программа может больше не работать так, как было первоначально задумано.
В обработчиках ошибок также можно использовать вложенный блок кода Try...Catch. Например, если первая попытка прочитать данные с дисковода оказалась неудачной и сгенерировала ошибку времени исполнения, следующий обработчик ошибок использует для единственной повторной попытки выполнения операции второй блок Try...Catch,:
Try
PictureBox1.Image = _
System.Drawing.Bitmap.FromFile ("a:\Fileopen.bmp")
Catch
MsgBox("Вставьте дискету в дисковод A, и нажмите OK!")
Try
PictureBox1.Image = _
System.Drawing.Bitmap.FromFile ("a:\Fileopen.bmp")
Catch
MsgBox("Загрузка файла невозможна")
Button1.Enabled = False
End Try
End Try
Если пользователь после появления сообщения с запросом вставит дискету в дисковод, второй блок Try откроет файл без ошибки. Однако если связанная с файлом ошибка времени исполнения появится снова, второй блок Catch выведет сообщение о том, что загрузка файла теперь невозможна, и отключит кнопку.
В основном, вложенные обработчики ошибок Try...Catch хорошо работают, когда не требуется совершать много повторных попыток. Если требуется выполнить проблемное действие много раз, используйте переменную для подсчета попыток, или разработайте функцию, которая будет содержать обработчик ошибок и которая может быть вызвана из процедур событий много раз. (За дополнительной информацией о создании функций обратитесь к следующей лекции.)
Обработчики ошибок являются не только механизмом для защиты программы от ошибок времени исполнения. Например, следующий код программы, чтобы проверить перед открытием файла его наличие на диске, использует метод File.Exists из пространства имен System.IO библиотеки классов .NET Framework:
If File.Exists("a:\Fileopen.bmp") Then
PictureBox1.Image = _
System.Drawing.Bitmap.FromFile ("a:\Fileopen.bmp")
Else
MsgBox("Не могу найти Fileopen.bmp на диске A.")
End If
Этот оператор If $$\dots$$ Then не является обработчиком ошибок, так как он не предотвращает остановку программы из-за ошибки времени исполнения. Это просто методика проверки, которую некоторые программисты называют защитным программированием. Этот оператор использует удобный метод из библиотеки классов .NET Framework, чтобы проверить возможность выполнения файловой операции, прежде чем на самом деле пытаться ее выполнить. И, в данном конкретном случае, поверка наличия файла с помощью метода .NET Framework работает быстрее, чем ожидание, пока Visual Basic сгенерирует исключение и восстановится после ошибки времени исполнения с помощью обработчика ошибок.
Imports System.IO
За дополнительной информацией об использовании оператора Imports для использования объектов, свойств и методов из библиотек классов .NET Framework обратитесь к лекции 5 .Когда нужно использовать защитные методики программирования, а когда обработчики ошибок? Ответ зависит от того, насколько часто, по вашему мнению, будет возникать проблема с операторами, которые вы планируете использовать. Если исключение или ошибка времени исполнения будет возникать довольно редко, скажем, менее чем в 25% случаев исполнения данного конкретного кода, то использование обработчика ошибок может оказаться наиболее эффективным способом. Обработчики ошибок также более удобны, если у вас более одного проверяемого условия, и если вы хотите предоставить пользователю различные возможности реакции на ошибку. Однако если существует реальная возможность того, что данный кусок кода будет приводить к ошибкам времени исполнения в более чем 25% случаев его исполнения, то обычно защитная методика программирования является наиболее эффективным способом управления. Как уже было сказано при обсуждении блока кода If $$\dots$$ Then, метод File.Exists на самом деле работает быстрее, чем использование обработчика ошибок Try...Catch, так что имеет смысл использовать защитную методику программирования, если большое значение имеет производительность. Наконец, лучше всего использовать в коде комбинацию защитной методики программирования и структурной обработки ошибок.
Прежде чем вы перейдете к следующей лекции, посмотрите на еще один вариант синтаксиса блоков кода Try...Catch, который может быть полезен - оператор Exit Try. Exit Try - это быстрая и простая "грубая" методика преждевременного выхода из блока кода Try...Catch ; если вы уже писали программы на Visual Basic, то вы можете заметить его сходство с операторами Exit For и Exit Sub, которые позволяют раньше времени покидать структурные конструкции. С помощью оператора Exit Try можно полностью покинуть текущий блок кода Try или Catch. Если есть блок кода Finally, то этот код будет выполнен, однако Exit Try позволяет перепрыгнуть через все остальные операторы Try или Catch.
В следующем примере процедуры показано, как работает оператор Exit Try. Сначала он проверяет, установлено ли свойство Enabled объекта PictureBox1 в значение PictureBox1 - это может указывать на то, что область вывода изображений еще не готова к приему данных. Если область вывода еще не доступна, то оператор Exit Try пропускает остальную часть блока кода до конца блока Catch, и попытка загрузки файла не производится.
Try
If PictureBox1.Enabled = False Then Exit Try
PictureBox1.Image = _
System.Drawing.Bitmap.FromFile ("a:\Fileopen.bmp")
Catch
Retries += 1
If Retries <= 2 Then
MsgBox("Пожалуйста, вставьте дискету в дисковод A!")
Else
MsgBox("Загрузка файла невозможна")
Button1.Enabled = False
End If
End Try
Этот пример дополняет последний обработчик ошибок, с которым вы экспериментировали в этой лекции (проект Exit Try в контексте этой программы, снова загрузите проект Exit Try. Вам также потребуется использовать окно Properties (Свойства), чтобы отключить объект вывода изображений в форме (другими словами, установить его свойство Enabled на значение False ).
Поздравляем! Вы изучили много важных базовых методик программирования на Visual Basic .NET и научились писать обработчики ошибок. Теперь вы можно перейти к более сложным вопросам программирования.
| Чтобы | Сделайте следующее |
|---|---|
| Обнаружить и обработать ошибки времени исполнения | Создайте с помощью блоков кода Try $$\dots$$ Catch обработчик ошибок. Например, следующий код обработчика ошибок проверяет проблемы с путем или дисководом: Try
PictureBox1.Image = _
System.Drawing.Bitmap.FromFile _
("a:\fileopen.bmp")
Catch
MsgBox("Проверьте путь или вставьте диск")
Finally
MsgBox("Обработка ошибок завершена")
End Try
|
| Проверить в обработчике события конкретные условия ошибки | Используйте оператор Catch When и свойство Err.Number. Например: Try
PictureBox1.Image = _
System.Drawing.Bitmap.FromFile _
("a:\fileopen.bmp")
Catch When Err.Number = 53 ' если File Not Found
MsgBox("Проверьте путь или вставьте диск")
Catch When Err.Number = 7 ' если Out Of Memory
MsgBox("Это действительно точечный рисунок?", , _
Err.Description)
Catch
MsgBox("Проблема с загрузкой файла", , _
Err.Description)
End Try
|
| Создать в программе собственные ошибки | Используйте метод Err.Raise. Например, следующий код генерирует ошибку Disk Full и обрабатывает ее: Try
Err.Raise(61) ' генерируем ошибку Disk Full
Catch When Err.Number = 61
MsgBox("Ошибка: Диск заполнен")
End Try
|
| Написать вложенные обработчики ошибок Try $$\dots$$ Catch | Поместите один блок кода Try $$\dots$$ Catch внутри другого. Например: Try
PictureBox1.Image = _
System.Drawing.Bitmap.FromFile _
("a:\fileopen.bmp")
Catch
MsgBox("Вставьте диск в дисковод A!")
Try
PictureBox1.Image = _
System.Drawing.Bitmap.FromFile _
("a:\fileopen.bmp")
Catch
MsgBox("Загрузка изображения отключена")
Button1.Enabled = False
End Try
End Try
|
| Выйти из текущего блока кода Try или Catch | Используйте в блоке кода Try или Catch оператор Exit Try. Например: If PictureBox1.Enabled = False Then Exit Try |
Для получения официальных документов о завершении программы дополнительного профессионального образования (удостоверения о повышении квалификации, дипломов о профессиональной переподготовке и MBA) необходимо предоставить:
Внимание! Вы можете не заказывать доставку бумажной версии официального документы, а скачать его в электронном виде и распечатать самостоятельно. Информация о выданном документе в течение 1 месяца загружается в Федеральную информационную систему «Федеральный реестр сведений о документах об образовании и (или) о квалификации, документах об обучении» - ФИС ФРДО.
Доступ на новый сайт осуществляется с использованием адреса электронной почты, который был указан вами при регистрации на "старом". Мы постарались перенести все ваши данные с прежнего ресурса, однако не исключена вероятность потери части информации.
При возникновении проблемы со входом, воспользуйтесь функцией сброса пароля
Если вы обнаружите несоответствия, пожалуйста, сообщите нам.