Behandlung von Ausnahmen in der Profilerstellungs-API
Ausnahmebenachrichtigungen sind diejenigen Benachrichtigungen, die am schwierigsten zu beschreiben und zu verstehen sind. In diesem Thema wird die Ausnahmeverarbeitung beschrieben, und es wird erklärt, wie die Profilerstellungs-API verschiedene Typen von Ausnahmen behandelt.
Flussdiagramm für Ausnahmebenachrichtigungen
Die Ausnahmeverarbeitung ist grundsätzlich komplex. Die in diesem Thema beschriebenen Ausnahmebenachrichtigungen liefern alle Informationen, die ein anspruchsvoller Profiler benötigt, um die Phase (Suchphase oder Entladephase), den Frame, den filter-Block und den finally-Block zu verfolgen, der für jeden Thread in dem Prozess ausgeführt wird, für den das Profil erstellt wird. Ausnahmebenachrichtigungen liefern keine ThreadIDs, aber Sie können die ICorProfilerInfo::GetCurrentThreadID-Methode aufrufen, um festzustellen, welcher verwaltete Thread die Ausnahme ausgelöst hat.
Die folgende Abbildung zeigt, wie der Codeprofiler verschiedene Rückrufe empfängt, wenn er Ausnahmeereignisse überwacht. Jeder Thread startet im normalen Ausführungszustand. Wenn der Thread in einem Zustand innerhalb des Ausnahmesystems ist (in der Suchphase oder der Entladephase), wird er durch das Ausnahmesystem ausgeführt. Alle Rückrufe, die nicht mit Ausnahmen verbunden sind (z. B. ICorProfilerCallback::ObjectAllocated) und die auftreten, während der Thread in einem dieser Zustände ist, können dem Ausnahmesystem selbst zugeordnet werden. Wenn der Thread in einem Zustand außerhalb des Ausnahmesystems ist, führt er beliebigen verwalteten Code aus.
Ausnahmerückrufsequenz
Geschachtelte Ausnahmen
Threads, die bei der Verarbeitung einer Ausnahme auf verwalteten Code gestoßen sind, könnten eine weitere Ausnahme auslösen, die zu einer ganz neuen Phase der Ausnahmenbehandlung führen würde. (Diese neue Phase wird in der Abbildung oben als "Neue Ausnahmebehandlungsphase" dargestellt.) Wenn eine solche geschachtelte Ausnahme diefilter/finally/catch-Blöcke der ursprünglichen Ausnahme mit dem Escapezeichen versieht, kann sich das in folgender Weise auf die ursprüngliche Ausnahme auswirken:
Wenn die geschachtelte Ausnahme innerhalb eines filter-Blocks aufgetreten ist und den filter-Block mit einem Escapezeichen versieht, wird angenommen, dass der filter-Block false zurückgibt, und die erste Phase wird fortgesetzt.
Wenn die geschachtelte Ausnahme innerhalb eines finally-Blocks aufgetreten ist und den finally-Block mit einem Escapezeichen versieht, wird die Verarbeitung der ursprünglichen Ausnahme nicht mehr aufgenommen.
Wenn die geschachtelte Ausnahme innerhalb eines catch-Blocks aufgetreten ist und den catch-Block mit einem Escapezeichen versieht, wird die Verarbeitung der ursprünglichen Ausnahme nicht mehr aufgenommen.
Nicht verwaltete Handler
Eine Ausnahme kann in nicht verwaltetem Code behandelt werden. In diesem Fall sieht der Profiler die Entladephase, erhält jedoch keine Benachrichtigung von catch-Handlern. Die Ausführung wird einfach ganz normal im nicht verwalteten Code fortgesetzt. Ein Profiler, der nicht verwalteten Code sieht, kann diese Situation erkennen, während ein Profiler, der sich nur auf verwalteten Code bezieht, eine Reihe von Punkten sehen kann, darunter z. B. Folgendes:
Einen ICorProfilerCallback::UnmanagedToManagedTransition-Rückruf, wenn der nicht verwaltete Code verwalteten Code aufruft oder dazu zurückkehrt.
Thread-Beendigung (wenn der nicht verwaltete Code am Stamm des Threads war).
Anwendungsbeendigung (wenn der nicht verwaltete Code die Anwendung beendet).
CLR-Handler
Eine Ausnahme könnte von der Common Language Runtime (CLR) selbst behandelt werden. In diesem Fall sieht der Profiler die Entladephase, erhält jedoch keine Benachrichtigung von catch-Handlern. Er könnte erkennen, dass die Ausführung in verwaltetem oder nicht verwaltetem Code normal wieder aufgenommen wird.
Nicht behandelte Ausnahmen
Standardmäßig führt eine nicht behandelte Ausnahme in .NET Framework, Version 2.0, zum Abbruch des Prozesses. Mit einem Anwendungskompatibilitätsflag können Sie die Einhaltung der Ausnahmerichtlinie von .NET Framework, Version 1, erzwingen, wie in Ausnahmen in verwalteten Threads beschrieben.