try-catch (C#-Referenz)try-catch (C# Reference)

Die try-catch-Anweisung besteht aus einem try-Block gefolgt von einer oder mehreren catch-Klauseln, die Handler für verschiedene Ausnahmen angeben.The try-catch statement consists of a try block followed by one or more catch clauses, which specify handlers for different exceptions.

HinweiseRemarks

Wenn eine Ausnahme ausgelöst wird, sucht die Common Language Runtime (CLR) nach der catch-Anweisung, die diese Ausnahme behandelt.When an exception is thrown, the common language runtime (CLR) looks for the catch statement that handles this exception. Wenn die derzeit ausgeführte Methode keinen solchen catch-Block enthält, betrachtet die CLR die Methode, die die aktuelle Methode aufgerufen hat, dann die vorhergehende in der Aufrufliste usw.If the currently executing method does not contain such a catch block, the CLR looks at the method that called the current method, and so on up the call stack. Wenn kein catch-Block gefunden wird, zeigt die CLR dem Benutzer eine Meldung über eine nicht behandelte Ausnahme an und beendet die Ausführung des Programms.If no catch block is found, then the CLR displays an unhandled exception message to the user and stops execution of the program.

Der try -Block enthält den überwachten Code, der möglicherweise die Ausnahme verursacht.The try block contains the guarded code that may cause the exception. Der Block wird ausgeführt, bis eine Ausnahme ausgelöst wird, oder bis er erfolgreich abgeschlossen wird.The block is executed until an exception is thrown or it is completed successfully. Beispielsweise löst der folgende Versuch, ein null-Objekt umzuwandeln, die NullReferenceException-Ausnahme aus:For example, the following attempt to cast a null object raises the NullReferenceException exception:

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

Zwar kann die catch-Klausel ohne Argumente verwendet werden, um jeden beliebigen Ausnahmetyp abfangen, dies wird jedoch nicht empfohlen.Although the catch clause can be used without arguments to catch any type of exception, this usage is not recommended. Im Allgemeinen sollten Sie nur solche Ausnahmen abfangen, bei denen Sie wissen, wie die Wiederherstellung durchgeführt wird.In general, you should only catch those exceptions that you know how to recover from. Daher sollten Sie immer ein von System.Exception abgeleitetes Objektargument angeben, zum Beispiel:Therefore, you should always specify an object argument derived from System.Exception For example:

catch (InvalidCastException e)   
{  
}  

Es ist möglich, mehrere spezifische catch-Klauseln in derselben try-catch-Anweisung zu verwenden.It is possible to use more than one specific catch clause in the same try-catch statement. In diesem Fall ist die Reihenfolge der catch-Klauseln wichtig, da die catch-Klauseln nacheinander überprüft werden.In this case, the order of the catch clauses is important because the catch clauses are examined in order. Fangen Sie spezifischere Ausnahmen vor den weniger spezifischen ab.Catch the more specific exceptions before the less specific ones. Der Compiler erzeugt einen Fehler, wenn Sie Ihre catch-Blöcke so anordnen, dass ein neuerer Block nie erreicht werden kann.The compiler produces an error if you order your catch blocks so that a later block can never be reached.

Die Verwendung von catch-Argumenten ist eine Möglichkeit zum Filtern der Ausnahmen, die Sie behandeln möchten.Using catch arguments is one way to filter for the exceptions you want to handle. Sie können auch einen Prädikatausdruck verwenden, der die Ausnahme weiter untersucht, um zu entscheiden, ob Sie sie behandeln möchten.You can also use a predicate expression that further examines the exception to decide whether to handle it. Wenn der Prädikatausdruck „false“ zurückgibt, wird die Suche nach einem Ausnahmehandler fortgesetzt.If the predicate expression returns false, then the search for a handler continues.

catch (ArgumentException e) when (e.ParamName == "…")  
{  
}  

Ausnahmefilter sind dem Abfangen und erneuten Auslösen vorzuziehen (siehe nachfolgende Erläuterung), da der Filter den Stapel nicht beschädigt.Exception filters are preferable to catching and rethrowing (explained below) because filters leave the stack unharmed. Wenn ein späterer Handler den Stapel löscht, können Sie feststellen, wo die Ausnahme ursprünglich herkam, und nicht nur die letzte Stelle, an der sie erneut ausgelöst wurde.If a later handler dumps the stack, you can see where the exception originally came from, rather than just the last place it was rethrown. Filterausdrücke für Ausnahmen werden häufig zu Protokollierungszwecken eingesetzt.A common use of exception filter expressions is logging. Sie können eine Prädikatfunktion erstellen, die immer FALSE zurückgibt und außerdem Ausgaben in ein Protokoll schreibt, und Sie können Ausnahmen protokollieren, wenn sie auftreten, ohne sie zu behandeln und erneut auszulösen.You can create a predicate function that always returns false that also outputs to a log, you can log exceptions as they go by without having to handle them and rethrow.

Eine throwcatch-Anweisung kann in einem -Block verwendet werden, um die von der catch-Anweisung abgefangene Ausnahme erneut auszulösen.A throw statement can be used in a catch block to re-throw the exception that is caught by the catch statement. Im folgenden Beispiel werden Quellinformationen aus einer IOException-Ausnahme extrahiert, anschließend wird die Ausnahme in der übergeordneten Methode ausgelöst.The following example extracts source information from an IOException exception, and then throws the exception to the parent method.

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;  
}  

Sie können eine Ausnahme abfangen und eine andere Ausnahme auslösen.You can catch one exception and throw a different exception. Wenn Sie dies tun, geben Sie die abgefangene Ausnahme als innere Ausnahme an, wie im folgenden Beispiel gezeigt.When you do this, specify the exception that you caught as the inner exception, as shown in the following example.

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

Sie können eine Ausnahme auch erneut auslösen, wenn eine angegebene Bedingung erfüllt ist, wie im folgenden Beispiel gezeigt.You can also re-throw an exception when a specified condition is true, as shown in the following example.

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

Initialisieren Sie innerhalb eines try-Blocks nur Variablen, die auch in diesem deklariert sind.From inside a try block, initialize only variables that are declared therein. Andernfalls kann eine Ausnahme auftreten, bevor die Ausführung des Blocks abgeschlossen ist.Otherwise, an exception can occur before the execution of the block is completed. Beispiel: Im folgenden Codebeispiel wird die n-Variable innerhalb des try-Blocks initialisiert.For example, in the following code example, the variable n is initialized inside the try block. Beim Versuch, diese Variable außerhalb des try-Blocks in der Write(n)-Anweisung zu verwenden, wird ein Compilerfehler generiert.An attempt to use this variable outside the try block in the Write(n) statement will generate a compiler error.

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);  
}  

Weitere Informationen zu „catch“ finden Sie unter try-catch-finally.For more information about catch, see try-catch-finally.

Ausnahmen in asynchronen MethodenExceptions in Async Methods

Eine asynchrone Methode wird mit einem async-Modifizierer gekennzeichnet und enthält in der Regel eine oder mehrere await-Ausdrücke oder -Anweisungen.An async method is marked by an async modifier and usually contains one or more await expressions or statements. Ein „await“-Ausdruck wendet den await-Operator auf ein Task oder Task<TResult> an.An await expression applies the await operator to a Task or Task<TResult>.

Wenn ein await-Ausdruck in der asynchchronen Methode erreicht wird, wird die Ausführung der Methode angehalten, bis die erwartete Aufgabe abgeschlossen ist.When control reaches an await in the async method, progress in the method is suspended until the awaited task completes. Wenn die Aufgabe abgeschlossen ist, kann die Ausführung in der Methode fortgesetzt werden.When the task is complete, execution can resume in the method. Weitere Informationen finden Sie unter Asynchrone Programmierung mit Async und Await und Ablaufsteuerung in asynchronen Programmen.For more information, see Asynchronous Programming with async and await and Control Flow in Async Programs.

Die abgeschlossene Aufgabe, auf die await angewendet wird, kann sich aufgrund einer unbehandelten Ausnahme in der Methode, die die Aufgabe zurückgibt, in einem fehlerhaften Zustand befinden.The completed task to which await is applied might be in a faulted state because of an unhandled exception in the method that returns the task. Das Warten auf die Aufgabe löst eine Ausnahme aus.Awaiting the task throws an exception. Eine Aufgabe kann auch in einem abgebrochenen Zustand enden, wenn der asynchrone Prozess, der sie zurückgibt, abgebrochen wird.A task can also end up in a canceled state if the asynchronous process that returns it is canceled. Das Warten auf eine abgebrochene Aufgabe löst eine OperationCanceledException aus.Awaiting a canceled task throws an OperationCanceledException. Weitere Informationen zum Abbrechen eines asynchronen Prozesses finden Sie unter Feinabstimmung der Async-Anwendung.For more information about how to cancel an asynchronous process, see Fine-Tuning Your Async Application.

Um die Ausnahme abzufangen, warten Sie in einem try-Block auf die Aufgabe, und fangen Sie die Ausnahme im zugehörigen catch-Block ab.To catch the exception, await the task in a try block, and catch the exception in the associated catch block. Ein Beispiel hierfür finden Sie im Abschnitt „Beispiel“.For an example, see the "Example" section.

Eine Aufgabe kann sich in einem fehlerhaften Zustand befinden, da mehrere Ausnahmen in der erwarteten asynchronen Methode aufgetreten sind.A task can be in a faulted state because multiple exceptions occurred in the awaited async method. Beispielsweise kann die Aufgabe das Ergebnis eines Aufrufs an Task.WhenAll sein.For example, the task might be the result of a call to Task.WhenAll. Wenn Sie auf eine solche Aufgabe warten, wird nur eine der Ausnahmen abgefangen, und Sie können nicht vorhersagen, welche Ausnahme abgefangen wird.When you await such a task, only one of the exceptions is caught, and you can't predict which exception will be caught. Ein Beispiel hierfür finden Sie im Abschnitt „Beispiel“.For an example, see the "Example" section.

BeispielExample

Im folgenden Beispiel enthält der try-Block einen Aufruf der ProcessString-Methode, die eine Ausnahme verursachen kann.In the following example, the try block contains a call to the ProcessString method that may cause an exception. Die catch-Klausel enthält den Ausnahmehandler, der lediglich eine Meldung auf dem Bildschirm anzeigt.The catch clause contains the exception handler that just displays a message on the screen. Wenn die throw-Anweisung aus MyMethod heraus aufgerufen wird, sucht das System nach der catch-Anweisung und zeigt die Meldung Exception caught an.When the throw statement is called from inside MyMethod, the system looks for the catch statement and displays the message 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.
     * */

BeispielExample

Im folgenden Beispiel werden zwei catch-Blöcke verwendet, und die spezifischste Ausnahme, die an erster Stelle steht, wird abgefangen.In the following example, two catch blocks are used, and the most specific exception, which comes first, is caught.

Um die allgemeinste Ausnahme abzufangen, können Sie die throw-Anweisung in ProcessString durch die folgende Anweisung ersetzen: throw new Exception().To catch the least specific exception, you can replace the throw statement in ProcessString with the following statement: throw new Exception().

Wenn Sie den allgemeinsten catch-Block im Beispiel an erster Stelle platzieren, wird die folgende Fehlermeldung angezeigt: A previous catch clause already catches all exceptions of this or a super type ('System.Exception').If you place the least-specific catch block first in the example, the following error message appears: 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.
*/

BeispielExample

Im folgenden Beispiel wird die Ausnahmebehandlung für asynchrone Methoden veranschaulicht.The following example illustrates exception handling for async methods. Um eine von einer asynchronen Aufgabe ausgelöste Ausnahme abzufangen, platzieren Sie den await-Ausdruck in einem try-Block, und fangen Sie die Ausnahme in einem catch-Block ab.To catch an exception that an async task throws, place the await expression in a try block, and catch the exception in a catch block.

Heben Sie die Auskommentierung der Zeile throw new Exception im Beispiel auf, um die Ausnahmebehandlung zu veranschaulichen.Uncomment the throw new Exception line in the example to demonstrate exception handling. Die IsFaulted-Eigenschaft der Aufgabe wird auf True festgelegt, die Exception.InnerException-Eigenschaft der Aufgabe auf die Ausnahme, und die Ausnahme wird im catch-Block abgefangen.The task's IsFaulted property is set to True, the task's Exception.InnerException property is set to the exception, and the exception is caught in the catch block.

Heben Sie die Auskommentierung der Zeile throw new OperationCancelledException auf, um zu veranschaulichen, was beim Abbrechen eines asynchronen Prozesses passiert.Uncomment the throw new OperationCancelledException line to demonstrate what happens when you cancel an asynchronous process. Die IsCanceled-Eigenschaft der Aufgabe wird auf true festgelegt, und die Ausnahme wird im catch-Block abgefangen.The task's IsCanceled property is set to true, and the exception is caught in the catch block. Unter bestimmten Bedingungen, die für dieses Beispiel nicht gelten, wird die IsFaulted-Eigenschaft der Aufgabe auf true und IsCanceled auf false festgelegt.Under some conditions that don't apply to this example, the task's IsFaulted property is set to true and IsCanceled is set to 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

BeispielExample

Das folgende Beispiel veranschaulicht die Behandlung von Ausnahmen in Fällen, in denen mehrere Aufgaben zu mehreren Ausnahmen führen können.The following example illustrates exception handling where multiple tasks can result in multiple exceptions. Der try-Block wartet auf die Aufgabe, die von einem Aufruf von Task.WhenAll zurückgegeben wird.The try block awaits the task that's returned by a call to Task.WhenAll. Die Aufgabe ist abgeschlossen, wenn die drei Aufgaben abgeschlossen sind, auf die WhenAll angewendet wird.The task is complete when the three tasks to which WhenAll is applied are complete.

Jede der drei Aufgaben löst eine Ausnahme aus.Each of the three tasks causes an exception. Der catch-Block iteriert durch die Ausnahmen, die in der Exception.InnerExceptions-Eigenschaft der Aufgabe stehen, die von Task.WhenAll zurückgegeben wurde.The catch block iterates through the exceptions, which are found in the Exception.InnerExceptions property of the task that was returned by 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

C#-ProgrammiersprachenspezifikationC# Language Specification

Weitere Informationen erhalten Sie unter C#-Sprachspezifikation. Die Sprachspezifikation ist die verbindliche Quelle für die Syntax und Verwendung von C#.

Siehe auchSee Also

C#-ReferenzC# Reference
C#-ProgrammierhandbuchC# Programming Guide
C#-SchlüsselwörterC# Keywords
try-, throw- und catch-Anweisungen (C++)try, throw, and catch Statements (C++)
AusnahmebehandlungsanweisungenException Handling Statements
throwthrow
try-finallytry-finally
Vorgehensweise: Explizites Auslösen von AusnahmenHow to: Explicitly Throw Exceptions