:: Меню ::

Головна
  • Про сайт
  • Введення
  • Середовище програмування VB .NET: Visual Studio .NET
  • Вирази, оператори і передача управління
  • Класи і об'єкти
  •  Спадкоємство і інтерфейси
  • Обробка подій і делегати
  • Обробка помилок в VB .NET
  • Форми Windows, графічний вивід і друк
  • Уведення-виведення
  •  Багатопотокові застосування
  • Підтримка баз-даних в VB .NET
  • Короткий огляд ASP .NET
  • Складки .NET, установка додатків і COM Interop
  • Книга для гостей
    Контакти
    Добавити у вибране

    :: Друзі ::

     
     

    :: Лічильники ::

    = =

     

     

     

     

    Ініціація виключень

    Вище вже мовилося про те, що метод Processfilе просто передає виключення в процедуру Sub Main, з якої він був викликаний. У процедурі Sub Mai n команда виклику теж поміщена в блок Try-catch, тому виключення буде оброблено. З іншого боку, таке рішення виглядає трохи наївно, а якщо написані вами класи використовуватимуться іншими програмістами, воно стає просто небезпечним. Але навіть якщо справа абияк обійдеться, користувачі вашої коди навряд чи будуть задоволені тим, що ви без розбору передаєте виключення, не намагаючись їх обробити.

    Краще спробувати по можливості «прибрати» за собою, а потім скористатися ключовим словом Throw, щоб передати об'єкт виключення зухвалій стороні. В розділі 4 згадувалося про те, що в VB .NET не підтримується детерміноване завершення. Отже, якщо ви створили об'єкт з методом D1 spose, цей метод слід викликати перед тим, як ініціювати виключення. Сказане відноситься і до відкриття файлів, і до отримання графічного контексту. У наступному фрагменті представлена умовна структура подібної коди:

    Try

    ' Створення локального об'єкту з методом Dispose

    ' Код. який може ініціювати виключення

    Catch(e As Exception)

    local Object.dispose()

    Throw e;

    End Try

    Якщо ви не викличете метод Dispose для свого локального об'єкту, то захоплені ресурси так і не будуть звільнені. Адже посилання на об'єкт існує лише в локальному коді; решта частин програми не володіє доступом до методу Dispose! З іншого боку, причина, по якій виникло виключення, залишається в силі, тому про виниклу проблему (наприклад, про невдалу операцію з файлом) потрібно повідомити зухвалий код. Для цього слід наново ініціювати виключення командою Throw, як це зроблено в другому виділеному рядку.

    Втім, якщо ви дійсно хочете програмувати «як годиться», не обмежуйтеся простим перезапуском виключення. Постарайтеся зробити свій код якомога більш інформативним і включите в об'єкт виключення додаткову інформацію. Для цього є три можливості.

    1. Додайте у виключення змістовне повідомлення і ініціюйте його наново. Можливо, нова інформація виявиться корисною.
    2. Ініціюйте виключення одне із стандартних типів, похідних від типу поточного виключення, щоб воно краще описувало ситуацію.
    3. Створіть новий клас виключення, похідний від типу поточного виключення, який описуватиме ситуацію краще, ніж будь-який із стандартних класів.

    Рішення розташовані за збільшенням пріоритету, і в ідеальному випадку слід завжди використовувати пункт 3. На практиці програмісти при виборі керуються своєю оцінкою того, яку інформацію про виключення необхідно передати для подальшої обробки.

    Для прикладу представте таку ситуацію: з джерела даних читаються пари «ключ/значення», і для останнього ключа не знаходиться парного значення. Програма припускає, що значення асоціюється з кожним ключем, тому при спробі читання виникає неожіданно'е виключення введення-виводу (читання даних з файлу описане в розділі 9).

    Тепер ви хочете повідомити про той, що відбувається зухвалій стороні. Щоб додати у виключення рядок, можна скористатися спеціальною версією конструктора класу Exception:

    Public Sub New(Byval message As String)

    У наступному фрагменті в об'єкт Ioexception додається новий рядок з повідомленням про відсутність значення для останнього ключа, після чого виключення ініціюється наново.

    Dim excep As New Iqexception("Missing value for last key") Throw excep

    Отримавши ініційоване виключення, зовнішній код отримує текст повідомлення методом Message класу Exception і дізнається про виниклу проблему.

    На практиці в подібних ситуаціях частіше виникає виключення класу Endofstream-exception, похідного від Ioexception. Операції з потоками даних розглядаються в розділі 9.

    Друга ситуація реалізується елементарно завдяки головному правилу спадкоємства: похідний клас завжди може використовуватися замість базового класу. Вам лише залишається ініціювати виключення похідного класу, яке краще підходить для даної ситуації.

    Останній випадок вимагає деякої додаткової роботи, оскільки для цього потрібно буде визначити клас, похідний від існуючого класу виключення. Припустимо, ви хочете визначити новий клас виключення, похідний від System. 10. loexception. Новий клас відрізняється від старого лише однією ReadOnly-свойством, що повертає ключ, з яким не асоціюється парне значення:

    Public Class Lastvaluelostexception Inherits System.I0.I0.Exception

    Private mkey As String

    Public Sub New(Byval thekey As String)

    Mybase.New("No value found for last key")

    mkey = thekey

    End Sub

    Public Readonly Property Lastkey() As String Get

    Return mkey

    End Get

    End Property

    End Class

    Звернете увагу: ім'я створеного класу виключення завершується словом Exception. Це стандартне правило, якому ми настійно рекомендуємо слідувати. Отримавши виключення Lastvaluelostexception, програміст може скористатися властивістю Lastkey, значення якої передається в конструкторі нового класу виключення, і отримати ключ, що не асоціюється із значенням. Наступний рядок забезпечує видачу правильній інформації методом Message базового класу Exception: Mybase.New("No value found for last key")

    У цьому рядку викликається конструктор базового класу (і кінець кінцем конструктор предка Exception).

    Можливо, ви відмітили, що в класі Lastvaluelostexception не перевизначаються інші методи — такі, як метод Tostring, успадкований від Exception. У стандартних ситуаціях об'єкти виключень завжди повинні виводити стандартні повідомлення.

    Як використовувати створений клас в програмі? Наприклад, якщо останній ключ без парного значення був рівний «oops», виключення ініціюватиметься наступною командою:

    Throw New Lastvaluelostexception("oops")

    Ієрархія виключень

    Ми створили новий клас виключень, похідний від Ioexcepti on, тому що потенційна проблема явно відносилася до категорії введення-виводу. Допустимо, ситуація має більш загальний характер і для базового класу не існує інших очевидних кандидатів, окрім класу Exception. Втім, це не зовсім вірно — кращий вибір існує завжди. Ми настійно рекомендуємо вибирати як базового не сам клас Exceptlon, а похідний від нього клас Appllcationexception.

    Річ у тому, що .NET Framework розрізняє виключення, що виникли в результаті проблем виконавчого середовища (наприклад, браки пам'яті або дискового простору) і проблем, обумовлених роботою вашого застосування. Саме виключення другої категорії мають бути похідними від Appllcationexcepti on, тому саме цей клас слід вибирати базовим при визначенні узагальнених виключень в програмі.

    Врахуйте, що клас Ioexception, як і багато стандартних виключень, є произ-водным від Exception, а не від Applicationexception.

    Виконавче середовище допомагає зробити наступний крок. Ієрархія виключень розходиться на дві гілки, показані на мал. 7.1.

    Мал. 7.1. Дві основні гілки ієрархії виключень

    Класи Exceptlon, Appllcationexcepti on і Systemexcepti on володіють однаковою функціональністю. Існування трьох класів замість одного — не більше ніж зручна абстракція, завдяки якій стає простіше зрозуміти виключення, що виникають у ваших програмах.

    Виключення як заміна для goto

    Обробка виключень у поєднанні з визначенням власних класів виключень дозволяє повністю відмовитися від використання Goto. Наприклад, в главе 3 був приведений приклад виправданого застосування Goto для переривання вкладених циклів, коли помилка відбувається у внутрішньому циклі. Програміст VB .NET у подібній ситуації просто укладає весь цикл в блок Try-catch, як показано нижче:

    Sub Main()

    Dim getdata As String

    Dim i, j As Integer

    Dim e As System.I0.I0Exception

    Try

    For i = 1 To 10

    For j = 1 To 100 Console.WriteC'Type the data, hit the Enter key between " & _

    "ZZZ to end: ") getdata _

    Console.ReadLine() If getdata = "ZZZ" Then

    e New System.I0.I0Exception("Data entry ended " & _

    "at user request") Throw e Else

    ' Обробка даних

    End If

    Next j

    Next i

    Catch

    Console.WriteLinete.Message)

    Console. Readline()

    End Try

    End Sub

    У приведеному вище фрагменті виділені рядки не можна об'єднати конструкцією наступного вигляду:

    Dim e As New System.IO.IOException("Data entry ended at user request")

    Унаслідок правил видимості VB .NET об'єкт виключення опиниться недоступним в секції Catch.

    Секція Finally

    При використанні блоків Try-catch нерідко існує код, який повинен виконуватися як при нормальному завершенні, так і при виникненні виключення. Наприклад, в обох випадках слід закрити файли, викликати методи Dispose і так далі Навіть в простому прикладі, приведеному на початку розділу, було потрібно команду Readline, щоб консольне вікно залишалося на екрані до натиснення клавіші Enter.

    Щоб деякий фрагмент виконувався незалежно від того, чи виникне в програмі виключення чи ні, в блок Try-catch включається секція Finally, виділена в наступному прикладі жирним шрифтом:

    Sub Main()

    Dim args(). argument As String

    args = Environment. Getcommandlineargs()

    Try

    Processfile(argsd))

    Catch

    Console.WriteLine("ERROR")

    Finally

    Console.WriteLine("Press enter to end")

    Console.ReadLine()

    End Try

    End Sub

    Код секції Finally виконується до передачі виключень внешнему.коду і до возвра-щенія з функції .

    Рекомендації по використанню виключень

    Виключення виглядають ефектно, і новачки часто схильні зловживати ними. Насправді, чи варто витрачати час на аналіз призначеного для користувача введення, коли можна просто ініціювати виключення? Не піддайтеся спокусі. При неправильному використанні обробка виключень істотно уповільнює роботу програми. Нижче приведені деякі рекомендації по використанню виключень в програмі.

    1. Виключення є ознакою аварійної ситуації; не використовуйте виключення для простий передачі інформації (ми бачили програму, в якій при успішному завершенні функції ініціювалося виключення Success_exception).
    2. Не замінюйте тривіальні перевірки обробкою виключень. Наприклад, виключення не варто застосовувати для перевірки досягнення кінця файлу (EOF).
    3. Уникайте роздробленої обробки виключень, при якій чи не кожна команда полягає в окремий блок Try-catch. Висновок всієї операції в один блок Try-catch зазвичай переважно використання декількох блоків.
    4. Не поглинайте виключення конструкціями виду Catch e As Excepti on з порожнім блоком команд, якщо для цього немає достатньо вагомих причин. Така конструкція еквівалентна бездумному застосуванню On Error Resume в старих програмах VB, і користуватися нею небажано по тих же причинах. Якщо в програмі відбулося виключення, обробіть його або передайте для подальшої обробки.
    5. Останню рекомендацію швидше можна назвати «правилом хорошого тону». Передаючи виключення в зовнішній код для подальшої обробки, додайте в нього нову інформацію (або визначите новий клас виключень), щоб зовнішній код міг точно визначити, що відбулося і які заходи були прийняті для того, щоб виправити ситуацію.

     




    :: Наша кнопка ::

    Отримати код:

    Підтримайте наш сайт і розмістіть нашу кнопку на своєму ресурсі.


    :: Реклама ::

    Скачати безкоштовно програму Microsoft Front Page 2003


    :: Посилання ::

    -


     

     

     


    Copyright ©