47 lines
1.5 KiB
C#
47 lines
1.5 KiB
C#
using Avalonia;
|
||
using Avalonia.Threading;
|
||
using Cowain.Base.Helpers;
|
||
using Microsoft.Extensions.Logging;
|
||
using System;
|
||
using System.Diagnostics;
|
||
using System.Threading.Tasks;
|
||
|
||
namespace Cowain.TestProject.Services;
|
||
|
||
public static class AvaloniaExceptionMiddleware
|
||
{
|
||
private static ILogger<App>? _logger;
|
||
public static void Install(ILogger<App>? logger)
|
||
{
|
||
_logger = logger;
|
||
// 1) 托管级:任意线程抛到崩溃
|
||
AppDomain.CurrentDomain.UnhandledException += (_, e) =>
|
||
Handle("AppDomain", e.ExceptionObject as Exception);
|
||
|
||
// 2) Task级:async void / 未 await 的Task
|
||
TaskScheduler.UnobservedTaskException += (_, e) =>
|
||
{
|
||
Handle("TaskScheduler", e.Exception);
|
||
e.SetObserved(); // 标记已处理,防止进程自杀
|
||
};
|
||
|
||
// 3) Dispatcher级:UI 线程中的未捕获
|
||
if (Application.Current != null)
|
||
Dispatcher.UIThread.UnhandledException += (_, e) => // 使用 Dispatcher.UIThread 代替 Application.Current.Dispatcher
|
||
{
|
||
Handle("Dispatcher", e.Exception);
|
||
e.Handled = true; // true=不继续冒泡
|
||
};
|
||
}
|
||
|
||
private static void Handle(string source, Exception? ex)
|
||
{
|
||
if (ex == null) return;
|
||
// TODO: 统一写日志、弹窗、上报……
|
||
var msg = $"[{source}] {ex}";
|
||
_logger?.LogError(ex, msg);
|
||
// 这里可以调自定义弹窗
|
||
// new ErrorWindow(ex).ShowDialog(Application.Current?.MainWindow);
|
||
}
|
||
}
|