Diagnostics SDK
Desktop integration
Capturing UI-thread exceptions in WPF and WinForms, and crash semantics on shutdown.
Desktop integration (WPF and WinForms)
Desktop UI frameworks route UI-thread exceptions through their own channels, so
AppDomain.UnhandledException alone misses them. The SDK hooks these channels via
reflection, which means the core package carries no UI-framework references and the
same package works everywhere. The catch: Init() must run on the UI thread.
WPF
public partial class App : Application
{
private readonly IDiagnosticsSession _diagnostics;
public App()
{
// On the UI thread, as early as possible:
_diagnostics = TicketManDiagnostics.Init();
}
protected override void OnExit(ExitEventArgs e)
{
_diagnostics.Dispose(); // flushes pending reports
base.OnExit(e);
}
}
Hooked automatically: Application.DispatcherUnhandledException, or the current
thread's Dispatcher.UnhandledException when the Application object does not
exist yet. That is why Init() must run on the UI thread.
The SDK never sets Handled = true, so your app's crash behavior is unchanged. If
the exception goes on to kill the process, the fatal-crash path also fires; the two
reports share a fingerprint and are grouped server-side.
WinForms
Same pattern. Call TicketManDiagnostics.Init() at the top of Main, before
Application.Run. Hooked automatically: Application.ThreadException.
If you use Application.SetUnhandledExceptionMode(UnhandledExceptionMode.ThrowException),
UI exceptions become fatal crashes instead and are captured by the crash path.
Shutdown and crash semantics
session.Dispose()flushes pending reports within a 5-second budget and detaches the non-fatal hooks.- The fatal-crash hook intentionally stays attached for the process lifetime, even
after disposal. With an async
Main, ausing-declared session is disposed while a crashing exception unwinds, before the runtime rethrows it at the entry point. The crash is still captured and spooled, then delivered the next time the app starts.
MAUI and other frameworks
Not auto-hooked in v1. Wire the framework's unhandled-exception event manually:
SomeFrameworkEvent += (s, e) => session.Client.CaptureException(e.Exception);