Оператор try-catch складається з блоку try. за яким слід одне або кілька пропозицій catch. задають обробники для різних виключень.
Примітки
При виникненні виключення загальномовне Виконавча (CLR) шукає оператор catch. який обробляє це виняток. Якщо поточний виконується метод не містить такої блок catch. Середа CLR виконує пошук в методі, який викликав поточний метод, і так далі вгору по стеку викликів. Якщо блок catch не знаходиться, то середовище CLR відображає користувачеві повідомлення про необробленому виключення і зупиняє виконання програми.
Блок try містить захищений код, який може викликати виключення. Цей блок виконується, поки не виникне виключення або поки він не буде успішно завершено. Наприклад, наступна спроба приведення об'єкта null викликає виключення NullReferenceException.
Хоча пропозиція catch може використовуватися без аргументів для перехоплення будь-якого типу виключення, таке використання не рекомендується. В цілому ви повинні перехоплювати тільки ті винятки, після яких ви знаєте, як виконати відновлення. Тому завжди слід вказувати аргумент об'єкта, похідний від Exception. наприклад:
В одному блоці try-catch можна використовувати кілька певних пропозицій catch. У цьому випадку важливий порядок пропозицій catch. оскільки пропозиції catch перевіряються по порядку. Перехоплюйте більш конкретні виключення перед менш конкретними. Компілятор видає помилку, якщо ви розташували блоки catch в такому порядку, що наступний блок може бути ніколи не досягнуть.
Використання аргументів catch представляє один із способів фільтрації винятків, які потрібно обробити. Ви також можете використовувати вираз предиката, яке додатково перевіряє виняток, щоб вирішити, чи слід його обробляти. Якщо вираз предиката повертає значення false, пошук обробника триває.
Фільтри винятків краще перехоплення і повторного виклику (пояснюється нижче), оскільки фільтри залишають стек в цілості й схоронності. Якщо наступний оброблювач розвантажує стек, ви можете побачити, звідки спочатку відбулося виключення, а не тільки останнє місце, в якому воно було повторно викликано. Зазвичай вираження фільтра винятків використовуються для ведення журналу. Ви можете створити функцію предиката, яка завжди повертає значення false, а також записує вихідний результат в журнал, щоб реєструвати виключення в журналі в міру їх надходження без необхідності їх обробки і повторного виклику.
Оператор throw. включений до блоку catch. дозволяє заново викликати виключення, перехоплений блоком catch. У наступному прикладі витягуються відомості про джерело з виключення IOException. а потім це виняток викликається для батьківського методу.
Ви можете перехоплювати один виняток і викликати інше виняток. При цьому слід вказати перехоплюється виняток як внутрішнє, як показано в наступному прикладі.
Ви також можете повторно викликати виключення при виконанні зазначеної умови, як показано в наступному прикладі.
У блоці try Ініціалізуйте тільки ті змінні, які в ньому оголошені. В іншому випадку до завершення виконання блоку може виникнути виняток. Наприклад, в наступному прикладі коду змінна n инициализируется всередині блоку try. Спроба використовувати дану змінну поза цим блоку try в інструкції Write (n) призведе до помилки компілятора.
Додаткові відомості про перехоплення виключень см. В розділі try-catch-finally.
Винятки в асинхронних методах
Асинхронний метод позначається модифікатором async і зазвичай містить одне або кілька виразів або інструкцій await. Вираз await застосовує оператор await до Task або Task
Завершена задача, до якої застосовується await. може перебувати в стані збою через необробленого виключення в методі, який повертає цю задачу. Очікування завдання викликає виняток. Завдання також може завершитися в скасованому стані, якщо скасовується асинхронний процес, який повертає цю задачу. Очікування скасованої завдання викликає OperationCanceledException. Додаткові відомості про те, як скасувати асинхронний процес, див. Розділ Точна настройка асинхронного додатки (C # і Visual Basic).
Для перехоплення виключення очікуйте завдання в блоці try і перехоплюйте це виняток у відповідному блоці catch. Див. Приклад в розділі «Приклад».
Завдання може бути в змозі збою, якщо в очікуваному асинхронному методі сталося кілька винятків. Наприклад, завдання може бути результатом виклику методу Task.WhenAll. При очікуванні такого завдання перехоплюється тільки одне з виключень і неможливо передбачити, яке виключення буде перехоплено. Див. Приклад в розділі «Приклад».
У наступному прикладі блок try містить виклик методу ProcessString. який може викликати виключення. Пропозиція catch містить обробник виключень, який просто відображає повідомлення на екрані. Коли оператор throw викликається з MyMethod. система здійснює пошук оператора catch і відображає повідомлення Exception caught.
У наступному прикладі використовуються два блоку catch і перехоплюється найбільш конкретний виняток, яке надійшло першим.
Щоб перехопити найменш конкретний виняток, можна замінити оператор throw в ProcessString наступним оператором: throw new Exception ().
Якщо в цьому прикладі першим помістити блок catch для перехоплення найменш конкретного винятку, то з'явиться наступне повідомлення про помилку: A previous catch clause already catches all exceptions of this or a super type ( 'System.Exception').
У наступному прикладі демонструється обробка винятків для асинхронних методів. Для перехоплення виключення, викликаного асинхронної завданням, помістіть вираз await в блок try і перехоплюйте це виняток у блоці catch.
У наступному прикладі демонструється обробка винятків, коли кілька завдань можуть призвести до кількох винятків. Блок try очікує завдання, яка повертається викликом методу Task.WhenAll. Це завдання завершується після завершення трьох завдань, до яких застосовується WhenAll.
Кожна з трьох завдань викликає виняток. Блок catch виконує ітерацію по винятків, які виявляються у властивості Exception.InnerExceptions завдання, повернутої методом Task.WhenAll.
Специфікація мови C #
Додаткові відомості див. У специфікації мови C #. Специфікація мови є розпорядчим джерелом інформації про синтаксис і використанні мови C #.