Files
OrpaonVision/OrpaonVision.ConfigApp/Infrastructure/Diagnostics/GlobalExceptionHandler.cs
2026-04-06 22:04:05 +08:00

91 lines
2.6 KiB
C#

using OrpaonVision.Core.Abstractions;
using System.Windows;
using System.Windows.Threading;
namespace OrpaonVision.ConfigApp.Infrastructure.Diagnostics;
/// <summary>
/// 全局未处理异常捕获器。
/// </summary>
public sealed class GlobalExceptionHandler : IDisposable
{
private readonly IAppLogger _logger;
private bool _registered;
/// <summary>
/// 构造全局异常处理器。
/// </summary>
/// <param name="logger">日志记录器。</param>
public GlobalExceptionHandler(IAppLogger logger)
{
_logger = logger;
}
/// <summary>
/// 注册全局异常事件。
/// </summary>
public void Register()
{
if (_registered)
{
return;
}
Application.Current.DispatcherUnhandledException += OnDispatcherUnhandledException;
AppDomain.CurrentDomain.UnhandledException += OnUnhandledException;
TaskScheduler.UnobservedTaskException += OnUnobservedTaskException;
_registered = true;
}
/// <summary>
/// 注销全局异常事件。
/// </summary>
public void Dispose()
{
if (!_registered)
{
return;
}
Application.Current.DispatcherUnhandledException -= OnDispatcherUnhandledException;
AppDomain.CurrentDomain.UnhandledException -= OnUnhandledException;
TaskScheduler.UnobservedTaskException -= OnUnobservedTaskException;
_registered = false;
}
private void OnDispatcherUnhandledException(object sender, DispatcherUnhandledExceptionEventArgs e)
{
var traceId = CreateTraceId();
_logger.LogError("捕获到 UI 线程未处理异常。", e.Exception, traceId);
MessageBox.Show(
$"程序发生未处理异常,操作已中断。{Environment.NewLine}TraceId: {traceId}",
"OrpaonVision.ConfigApp",
MessageBoxButton.OK,
MessageBoxImage.Error);
e.Handled = true;
}
private void OnUnhandledException(object? sender, UnhandledExceptionEventArgs e)
{
var traceId = CreateTraceId();
var exception = e.ExceptionObject as Exception;
_logger.LogError("捕获到应用域未处理异常。", exception, traceId);
}
private void OnUnobservedTaskException(object? sender, UnobservedTaskExceptionEventArgs e)
{
var traceId = CreateTraceId();
_logger.LogError("捕获到未观察的任务异常。", e.Exception, traceId);
e.SetObserved();
}
private static string CreateTraceId()
{
return Guid.NewGuid().ToString("N");
}
}