Fehlerbehandlung in C#: try/catch und fortgeschrittene Techniken für .NET

Online Python-Trainer für Anfänger

Lernen Sie Python einfach ohne theoretische Überlastung. Lösen Sie praktische Aufgaben mit automatischer Überprüfung und schreiben Sie Code direkt im Browser.

Kurs starten

Fortgeschrittene Fehlerbehandlung in C#: Vom einfachen try/catch zu industriellen Mustern

\n\n

Fehlerbehandlung ist nicht nur das Abfangen von Ausnahmen, sondern die Kunst, zuverlässige Systeme zu entwerfen. In C# (.NET) beschränken sich Entwickler oft auf das Konstrukt try/catch, aber die Plattform bietet weitaus leistungsfähigere Mechanismen. In diesem Artikel analysieren wir fortgeschrittene Techniken: von Ausnahmefiltern bis hin zu Wiederholungsmustern und der Übergabe von Fehlerkontexten.

\n\n

1. Ausnahmefilter: Präzision statt Platzhalter

\n\n

Ausnahmefilter (Exception Filters), die mit C# 6.0 eingeführt wurden, ermöglichen es, eine Bedingung für den Eintritt in einen catch-Block anzugeben, ohne die Ausnahme erneut auszulösen. Dies ist wesentlich sauberer als der klassische Ansatz mit einem if innerhalb des Blocks.

\n\n
try\n{\n    // Code, der eine Ausnahme auslösen kann\n    var result = ProcessData(input);\n}\ncatch (CustomException ex) when (ex.ErrorCode == 1001)\n{\n    // Verarbeite nur Fehler mit Code 1001\n    Log.Error($"Kritischer Fehler: {ex.Message}");\n    throw; // Bei Bedarf weiterleiten\n}\ncatch (CustomException ex) when (ex.IsRecoverable)\n{\n    // Behebbarer Fehler – protokollieren und fortfahren\n    Log.Warning($"Behebbarer Fehler: {ex.Message}");\n    RetryOperation();\n}
\n\n

Vorteile:

\n
    \n
  • Kein erneutes throw zur Filterung erforderlich.
  • \n
  • Verbesserte Lesbarkeit und Leistung (der Aufrufstapel wird nicht beschädigt).
  • \n
  • Mehrere catch-Blöcke mit unterschiedlichen Bedingungen können kombiniert werden.
  • \n
\n\n

2. Das "Wiederholungs"-Muster (Retry) und Polly

\n\n

Nicht alle Fehler sind fatal. Für vorübergehende Ausfälle (Netzwerkprobleme, Datenbanksperren) verwenden Sie das Muster der Wiederholungsversuche. Die integrierten Mittel von C# sind begrenzt, daher wird die Bibliothek Polly empfohlen.

\n\n
using Polly;\nusing Polly.Retry;\n\n// Definieren der Wiederholungsrichtlinie\nAsyncRetryPolicy retryPolicy = Policy\n    .Handle<HttpRequestException>() // Nur HTTP-Fehler behandeln\n    .WaitAndRetryAsync(\n        3, // Anzahl der Versuche\n        retryAttempt => TimeSpan.FromSeconds(Math.Pow(2, retryAttempt)), // Exponentielle Verzögerung\n        onRetry: (exception, timeSpan, retryCount, context) =>\n        {\n            Log.Warning($"Versuch {retryCount} fehlgeschlagen. Wiederholung in {timeSpan.Seconds} Sek.");\n        });\n\n// Anwenden der Richtlinie\nawait retryPolicy.ExecuteAsync(async () =>\n{\n    var response = await httpClient.GetAsync("https://api.example.com/data");\n    response.EnsureSuccessStatusCode();\n});
\n\n

Wichtig: Verwenden Sie keine unendlichen Wiederholungen. Geben Sie immer eine maximale Anzahl von Versuchen an und nutzen Sie Circuit Breaker, um das System vor kaskadierenden Ausfällen zu schützen.

\n\n

3. Korrekte Weitergabe von Ausnahmen: throw vs throw ex

\n\n

Einer der häufigsten Fehler ist der Verlust des Aufrufstapels. Der Unterschied zwischen throw und throw ex ist für das Debugging entscheidend.

\n\n
try\n{\n    // ...\n}\ncatch (Exception ex)\n{\n    // FALSCH: Verliert den ursprünglichen Stack\n    // throw ex;  \n\n    // RICHTIG: Behält den Stack\n    throw;\n\n    // ODER: Kontext hinzufügen, ohne das Original zu verlieren\n    // throw new ApplicationException("Fehler in Modul X", ex);\n}
\n\n

Wenn Sie Kontext hinzufügen müssen, verwenden Sie ExceptionDispatchInfo (aus dem Namespace System.Runtime.ExceptionServices) für die präzise Beibehaltung des Stacks beim Weiterwerfen zwischen Threads.

\n\n
ExceptionDispatchInfo.Capture(exception).Throw(); // Behält den ursprünglichen Stack
\n\n

4. Benutzerdefinierte Ausnahmen und Fehlerkontext

\n\n

Standardausnahmen enthalten oft keinen Geschäftskontext. Erstellen Sie Ihre eigenen Ausnahmeklassen mit zusätzlichen Eigenschaften.

\n\n
public class PaymentProcessingException : Exception\n{\n    public int OrderId { get; }\n    public dec                

Blogs

Buchempfehlungen