|
|||||||||||||||||||||||||||||||||||||||||||||
|
|||||||||||||||||||||||||||||||||||||||||||||
|
Обробка помилок в VB .NET
До справжнього моменту ми вдавали, що в наших програмах помилок не буває. Але
навіть в найнадійнішій програмі іноді виникають непередбачені ситуації —
наприклад, такі, як втрата мережевого з'єднання або відсутність паперу в принтері.
Звичайно, програміст в цьому не винен, але винити користувача в розриві зв'язку теж було
б несправедливо. Принаймні, в таких ситуаціях програма не повинна завершуватися аварійно.
Вона винна:
Втім, виконати ці
вимоги буває непросто. Мережевий код зазвичай ніяк не пов'язаний з об'єктами,
стан яких потрібно зберегти. Відповідно, програмістові потрібні засоби
для передачі управління і для сповіщення інших об'єктів про той, що відбувається,
щоб вони могли прийняти потрібні заходи. Так або інакше,
хороший програміст знає, що наш мир не ідеальний, а непередбачені ситуації
зустрічаються частіше, ніж хотілося б. У цьому розділі ми повернемося з небес на землю. Отже, на
відміну від колишніх версій VB в VB .NET підтримується механізм структурної
обробки виключень (або просто обробки виключень). У цьому розділі ви не
тільки познайомитеся з синтаксисом обробки виключень в додатках VB .NET, але
і дізнаєтеся, якими перевагами володіє цей механізм. Зокрема, при обробці
виключень відпадає необхідність навіть в більш або ме- її виправданому
застосуванні Goto, описаному в розділі 3. Проте ніщо хороше не дається безкоштовно,
тому ви також повинні пам'ятати про деякі тонкощі, пов'язані із структурною
обробкою виключень.
Перевірка
помилок і обробка виключень
Традиційний механізм
обробки помилок, що використався в колишніх версіях VB, а також в
програмуванні СОМ і Windows, заснований на перевірці повертаного значення функції
і виборі дій. Зазвичай для перевірки повертаного значення в програмі створюється
аналог конструкції Select Case, причому значення інтерпретуються абсолютно довільно.
Наприклад, в одному випадку 0 означає успіх, а в іншому — невдачу. А в приведеному
нижче фрагменті коди Vb6 коди виглядають і зовсім дивно: Select Case Error-number Case
57 Msgbox "Your printer may be off-line." Case
68 Msgbox "Is there а printer available?" ' Інші секції Case Case
Else ' Решта всіх випадків End Select
Подібні конструкції працюють, але їх важко читати і ще важче змінювати
в процесі супроводу програми. Можна упевнено сказати, що ця схема таїть в
собі широкі можливості для помилок програмування. Наприклад, ви можете
переплутати коди помилок або забути перевірити деякі з повертаних значень.
Крім того, писати один і той же код перевірки при кожному виклику функції Windows
API, принаймні, утомливо. Хоча в деяких ситуаціях повертане значення
доводиться перевіряти незалежно від вибраної схеми обробки помилок, не варто
перетворювати це на постійну практику. Також слід враховувати чинник ефективності:
структурна обробка виключень швидше програмується, віднімає менше часу
при супроводі, а нерідко і виконується швидше!
Підготовка
до структурної обробки виключень
Перш ніж переходити
до прикладів, що демонструють обробку виключень на практиці, необхідно
познайомитися з деякими обставинами. По-перше, при структурній обробці
виключень в програму включається додаткова гілка, яка автоматично
виконується при виникненні каких-або аварійних
ситуацій. Крім того, при обробці виключень VB .NET автоматично створює
об'єкт, що містить інформацію про помилку. Коли в програмі відбувається виключення, вбудований
механізм починає шукати обробник, відповідний для даного об'єкту
виключення (тобто для конкретної причини помилки). Мова йде не про набір
Goto, що заплутують логіку програми, — обробка виключення більше нагадує запасну
дорогу, що йде паралельно головній магістралі і пов'язану з нею
декількома переїздами, — справжній мрії будь-якого водія, що потрапив в пробку.
Якщо в програмі щось піде не так, управління автоматично передається гілці,
що містить логіку обробки виключень (якщо, звичайно, ви її запрограмували).
Після цього виключення або розглядається одним з обробників, або передається
далі по ланцюжку. У VB .NET
для обробки виключень існує синтаксична конструкція, звана блоком
Try-catch. Допустимо, у нас є консольний додаток Processfile. Передбачається,
що користувач запускає його в режимі командного рядка командою виду Processfile
імя_файла
Ім'я файлу передається у вигляді параметра. Як це зазвичай буває, користувачі
робитимуть все, щоб збити бідну програму з пантелику. Зокрема, вони можуть:
Програма
має бути написана так, щоб враховувати всі можливі помилки з боку користувача.
Нижче приведений приклад простого блоку Try-catch, який може входити в додаток
Processfile: Module Exceptionl
Sub Main() Dim args() As
String Try args = Environment.GetCommandLineArgs() Processfile(argsd)) Catch Console.WriteLine("ERROR") End
Try Console.WriteLine("Press enter to end") Console. Readline() End Sub
Sub Processfiletbyval filename As String) '
Обробка файлу Console.WriteLine("Am processing " & fname) End Sub End
Module Секція Try блоку
Try-catch містить «правильний» код — в даному прикладі це виклик
Processfile (виклик Environment.GetCommandLingArgs() поміщений в секцію Try,
тому що він теж може ініціювати виключення — наприклад, якщо ваша програма
працює на платформі, що не підтримує передачі аргументів в командному
рядку). Секція
Catch в блоці Try-catch необхідна, тому що деякі неуважні
користувачі не обертають уваги на вказівки. Якщо в приведеному фрагменті
користувач забуває ввести ім'я файлу, програма намагається звернутися до імені файлу,
що приводить до виключення Indexoutofrangeexceptl on, оскільки елемент з
вказаним індексом відсутній у файлі. При виникненні виключення управління
передається в додаткову гілку, тобто в блок Catch, який в нашому прикладі просто
виводить рядок ERROR в консольному вікні.
|
|
|||||||||||||||||||||||||||||||||||||||||||
|
|||||||||||||||||||||||||||||||||||||||||||||