Sdílet prostřednictvím


try-catch (Referenční dokumentace jazyka C#)

Příkaz try-catch se skládá z try bloku následuje jeden nebo více catch doložky zadejte popisovače pro různé výjimky.

Poznámky

Když je vyvolána výjimka, common language runtime (CLR) hledá catch příkazem, který zpracovává tuto výjimku.Pokud aktuálně vykonávajícího metoda neobsahuje takové catch blokovat CLR vyhledá na metodu, která se nazývá aktuální metody nahoru zásobníkem volání atd.Pokud ne catch blok, pak uživateli zobrazí zpráva neošetřené výjimky CLR a zastaví provádění programu.

try Blok obsahuje chráněné kód, který může způsobit výjimku.Blok je spuštěn, dokud je vyvolána výjimka nebo úspěšně dokončena.Například následující pokus přetypovat null objekt vyvolá NullReferenceException výjimky:

object o2 = null;
try
{
    int i2 = (int)o2;   // Error
}

Přestože catch klauzuli lze zachytit jakýkoli typ výjimky bez argumentů, toto použití není doporučeno.Obecně by pouze zachytit tyto výjimky, které víte, jak obnovit.Proto by měl vždy zadat argument objektu odvozené z Exception příklad:

catch (InvalidCastException e) 
{
}

Je možné použít více než jeden konkrétní catch ve stejném příkazu try-catch klauzule.V tomto případě pořadí catch klauzule je důležité, protože catch doložky jsou zkoumány v pořadí.Zachytit více specifické výjimky před ty méně konkrétní.Kompilátor vytvoří chybu, pokud jste objednání že vašich úlovků blokuje, takže později bloku lze dosáhnout nikdy.

A vyvolat příkaz lze použít v catch bloku znovu vyvolání výjimky, která je zachycena catch prohlášení.Následující příklad extrahuje zdroj informací z IOException výjimku a potom vyvolá výjimku metody nadřazené.

catch (FileNotFoundException e)
{
    // FileNotFoundExceptions are handled here.
}
catch (IOException e)
{
    // Extract some information from this exception, and then 
    // throw it to the parent method.
    if (e.Source != null)
        Console.WriteLine("IOException source: {0}", e.Source);
    throw;
}

Můžete zachytit výjimku a vyvolat různé výjimky.Pokud to uděláte, výjimky, která je zachycena jako vnitřní výjimka určete, jak je znázorněno v následujícím příkladu.

catch (InvalidCastException e) 
{
    // Perform some action here, and then throw a new exception.
    throw new YourCustomException("Put your error message here.", e);
}

Pokud je zadaná podmínka hodnotu true, jak je znázorněno v následujícím příkladu lze také znovu vyvolání výjimky.

catch (InvalidCastException e)
{
    if (e.Data == null)
    {
        throw;
    }
    else
    {
        // Take some action.
    }
 }

Z uvnitř try blokovat, inicializovat pouze proměnné, které jsou deklarovány v něm.Jinak výjimka může dojít před dokončením spuštění bloku.Například v následujícím příkladu kódu proměnné n je inicializován uvnitř try bloku.Pokus o použití této proměnné mimo try blok Write(n) příkaz vygeneruje chybu kompilátoru.

static void Main() 
{
    int n;
    try 
    {
        // Do not initialize this variable here.
        n = 123;
    }
    catch
    {
    }
    // Error: Use of unassigned local variable 'n'.
    Console.Write(n);
}

Další informace o úlovku, viz konstrukce try-catch-finally.

Výjimky v asynchronní metody

Asynchronní metody je označen asynchronní modifikátor a obvykle obsahuje jeden nebo více očekávat výrazy nebo příkazy.Aplikuje výraz await await operátor Task nebo Task.await Výrazu nelze provést v catch bloku nebo finally bloku.

Při řízení dosáhne await v asynchronní metody pokroku v metodě je pozastavena až do dokončení úkolu awaited.Po dokončení úkolu může pokračovat spuštění metody.Další informace naleznete v tématu Asynchronní programování pomocí modifikátoru Async a operátoru Await (C# a Visual Basic) a Řízení toku v asynchronních programech (C# a Visual Basic).

Dokončené úlohy, které await je použita může být ve stavu nezpracované výjimce v metodě, která vrátí úkolu.Úloha čeká na výjimku.Úlohu lze ukončit také zrušené státu Pokud zrušení asynchronní proces, který ji vrátí.Vyvolá čekají na zrušené úlohy OperationCanceledException.Další informace o tom, jak zrušit asynchronní proces viz Vyladění aplikace s modifikátorem Async (C# a Visual Basic).

K zachycení výjimky, kde čekají na úkolu v try blokovat a zachycení výjimky v souvisejícím catch bloku.Příklad naleznete v oddílu "Příklad".

Úkol může být ve stavu, protože v awaited asynchronní metody došlo k více výjimek.Úkol může být například výsledkem volání Task.WhenAll.Můžete očekávat takový úkol, je zachycena pouze některá z výjimek a nemůžete předpovědět, který k výjimce.Příklad naleznete v oddílu "Příklad".

Příklad

V následujícím příkladu try blok obsahuje volání ProcessString metodu, která může způsobit výjimku.catch Klauzule obsahuje pouze na obrazovce zobrazí zpráva obslužná rutina výjimky.Když throw nazývá z uvnitř MyMethod, vyhledá systém catch prohlášení a zobrazí zprávu Exception caught.

class TryFinallyTest
{
    static void ProcessString(string s)
    {
        if (s == null)
        {
            throw new ArgumentNullException();
        }
    }

    static void Main()
    {
        string s = null; // For demonstration purposes. 

        try
        {            
            ProcessString(s);
        }

        catch (Exception e)
        {
            Console.WriteLine("{0} Exception caught.", e);
        }
    }
}
    /*
    Output:
    System.ArgumentNullException: Value cannot be null.
       at TryFinallyTest.Main() Exception caught.
     * */

V následujícím příkladu jsou použity dva bloky catch a nejvíce specifické výjimky pochází první, je zachycena.

Nejméně specifickou výjimku zachytit, lze nahradit příkaz throw v ProcessString s následující příkaz: throw new Exception().

Pokud nejprve umístit blok catch specifické nejméně v příkladu se zobrazí následující chybová zpráva: A previous catch clause already catches all exceptions of this or a super type ('System.Exception').

class ThrowTest3
{
    static void ProcessString(string s)
    {
        if (s == null)
        {
            throw new ArgumentNullException();
        }
    }

    static void Main()
    {
        try
        {
            string s = null;
            ProcessString(s);
        }
        // Most specific: 
        catch (ArgumentNullException e)
        {
            Console.WriteLine("{0} First exception caught.", e);
        }
        // Least specific: 
        catch (Exception e)
        {
            Console.WriteLine("{0} Second exception caught.", e);
        }
    }
}
/*
 Output:
 System.ArgumentNullException: Value cannot be null.
 at Test.ThrowTest3.ProcessString(String s) ... First exception caught.
*/

Následující příklad ukazuje zpracování výjimek pro asynchronní metody.Zachytit výjimku, která vyvolala úkol aplikace asynchronní, umístěte await výraz v try blokovat a zachycení výjimky v catch bloku.

Odkomentujte throw new Exception řádek v příkladu, který demonstruje zpracování výjimek.Úkolu IsFaulted vlastnost True, úkolu Exception.InnerException vlastnost výjimky a výjimce v catch bloku.

Odkomentujte throw new OperationCancelledException řádku ukazují, co se stane když jste cancelan asynchronní proces.Úkolu IsCanceled vlastnost true, a výjimce v catch bloku.Za určitých podmínek, které neodpovídají například úkol na IsFaulted vlastnost true a IsCanceled je nastavena na false.

public async Task DoSomethingAsync()
        {
            Task<string> theTask = DelayAsync();

            try
            {
                string result = await theTask;
                Debug.WriteLine("Result: " + result);
            }
            catch (Exception ex)
            {
                Debug.WriteLine("Exception Message: " + ex.Message);
            }
            Debug.WriteLine("Task IsCanceled: " + theTask.IsCanceled);
            Debug.WriteLine("Task IsFaulted:  " + theTask.IsFaulted);
            if (theTask.Exception != null)
            {
                Debug.WriteLine("Task Exception Message: "
                    + theTask.Exception.Message);
                Debug.WriteLine("Task Inner Exception Message: "
                    + theTask.Exception.InnerException.Message);
            }
        }

        private async Task<string> DelayAsync()
        {
            await Task.Delay(100);

            // Uncomment each of the following lines to 
            // demonstrate exception handling. 

            //throw new OperationCanceledException("canceled");
            //throw new Exception("Something happened.");
            return "Done";
        }

        // Output when no exception is thrown in the awaited method: 
        //   Result: Done 
        //   Task IsCanceled: False 
        //   Task IsFaulted:  False 

        // Output when an Exception is thrown in the awaited method: 
        //   Exception Message: Something happened. 
        //   Task IsCanceled: False 
        //   Task IsFaulted:  True 
        //   Task Exception Message: One or more errors occurred. 
        //   Task Inner Exception Message: Something happened. 

        // Output when a OperationCanceledException or TaskCanceledException 
        // is thrown in the awaited method: 
        //   Exception Message: canceled 
        //   Task IsCanceled: True 
        //   Task IsFaulted:  False

Následující příklad ukazuje zpracování výjimek, kde více úkolů může vést více výjimek.try Bloku čeká úkol, který je vrácený voláním Task.WhenAll.Po dokončení tři úkoly, u kterých je použita WhenAll dokončení úkolu.

Všechny tři úkoly způsobí výjimku.catch Blok prochází výjimky, které se nacházejí v Exception.InnerExceptions vlastnost úkolu, který byl vrácen Task.WhenAll.

public async Task DoMultipleAsync()
{
    Task theTask1 = ExcAsync(info: "First Task");
    Task theTask2 = ExcAsync(info: "Second Task");
    Task theTask3 = ExcAsync(info: "Third Task");

    Task allTasks = Task.WhenAll(theTask1, theTask2, theTask3);

    try
    {
        await allTasks;
    }
    catch (Exception ex)
    {
        Debug.WriteLine("Exception: " + ex.Message);
        Debug.WriteLine("Task IsFaulted: " + allTasks.IsFaulted);
        foreach (var inEx in allTasks.Exception.InnerExceptions)
        {
            Debug.WriteLine("Task Inner Exception: " + inEx.Message);
        }
    }
}

private async Task ExcAsync(string info)
{
    await Task.Delay(100);

    throw new Exception("Error-" + info);
}

// Output: 
//   Exception: Error-First Task 
//   Task IsFaulted: True 
//   Task Inner Exception: Error-First Task 
//   Task Inner Exception: Error-Second Task 
//   Task Inner Exception: Error-Third Task

Specifikace jazyka C#

Další informace najdete v tématu Specifikace jazyka C#. Specifikace jazyka je úplným a rozhodujícím zdrojem pro syntaxi a použití jazyka C#.

Viz také

Úkoly

Postupy: Explicitní generování výjimek

Referenční dokumentace

Klíčová slova jazyka C#

try, throw a catch – příkazy (C++)

Příkazy zpracování výjimek (Referenční dokumentace jazyka C#)

throw (Referenční dokumentace jazyka C#)

try-finally (Referenční dokumentace jazyka C#)

Koncepty

Průvodce programováním v C#

Další zdroje

Referenční dokumentace jazyka C#