文章目录

.NET MAUI 是 .NET 跨平台原生 UI 的未来,将成为 .NET的一部分... 在 .NET MAUI 开发中,全局异常捕获是提升应用稳定性的关键。以下基于 .NET MAUI 官方实践,提供完整实现方案:
一、核心方法
通过重写 Application
类方法实现跨平台异常捕获:
csharp
// App.xaml.cs
public partial class App : Application
{
public App()
{
InitializeComponent();
MainPage = new MainPage();
// 注册全局异常处理器
AppDomain.CurrentDomain.UnhandledException += (sender, args) =>
{
var ex = (Exception)args.ExceptionObject;
HandleException(ex);
};
}
private void HandleException(Exception ex)
{
// 实现异常处理逻辑
Console.WriteLine($"全局异常: {ex.Message}");
// 可选:记录日志、通知用户或上报服务端
#if DEBUG
Application.Current?.MainPage?.DisplayAlert("错误", ex.Message, "确定");
#endif
}
}
二、平台适配技巧
-
Android 特殊处理
在
Platforms/Android/MainApplication.cs
添加:csharpAndroidEnvironment.UnhandledExceptionRaiser += (sender, args) => { Console.WriteLine($"Android 环境异常: {args.Exception}"); args.Handled = true; // 阻止应用崩溃 };
-
iOS/macOS 优化
通过
NSSetUncaughtExceptionHandler
捕获原生异常:csharp#if IOS || MACCATALYST ObjCRuntime.Runtime.MarshalManagedException += (_, e) => { Console.WriteLine($"Apple 平台异常: {e.Exception}"); e.ExceptionMode = ObjCRuntime.MarshalManagedExceptionMode.Disable; }; #endif
-
Windows
csharp
#elif WINDOWS
// For WinUI 3:
//
// * Exceptions on background threads are caught by AppDomain.CurrentDomain.UnhandledException,
// not by Microsoft.UI.Xaml.Application.Current.UnhandledException
// See: https://github.com/microsoft/microsoft-ui-xaml/issues/5221
//
// * Exceptions caught by Microsoft.UI.Xaml.Application.Current.UnhandledException have details removed,
// but that can be worked around by saved by trapping first chance exceptions
// See: https://github.com/microsoft/microsoft-ui-xaml/issues/7160
//
Microsoft.UI.Xaml.Application.Current.UnhandledException += (sender, args) =>
{
var exception = args.Exception;
if (exception.StackTrace is null)
{
exception = _lastFirstChanceException;
}
UnhandledException?.Invoke(sender,"Microsoft.UI.Xaml.Application.Current.UnhandledException", new UnhandledExceptionEventArgs(exception, true));
};
#endif
三、进阶实践
-
与日志系统集成
结合
Microsoft.Extensions.Logging
记录异常:csharpprivate void HandleException(Exception ex) { var logger = Handler.MauiContext.Services.GetService<ILogger<App>>(); logger?.LogError(ex, "全局异常捕获"); }
-
错误上报服务
异步上报到后端:
csharp_ = Task.Run(async () => { await MyErrorReportingService.ReportAsync(ex); });
-
用户友好提示
在主线程显示弹窗:
csharpMainThread.BeginInvokeOnMainThread(() => { MainPage?.DisplayAlert("系统错误", "已记录问题,请重试", "确定"); });
四、注意事项
-
作用范围
OnUnhandledException
:捕获 UI 线程异常AppDomain.UnhandledException
:捕获后台线程异常- 无法捕获原生崩溃(需平台特定工具)
-
调试模式差异
在
DEBUG
环境下建议显示详细错误,RELEASE
下隐藏技术细节:csharp#if RELEASE string message = "操作失败,请联系支持"; #else string message = ex.ToString(); #endif
-
性能影响
避免在异常处理器中执行耗时操作,建议异步处理日志/上报逻辑。
参考官方路线图:.NET MAUI 在 .NET 7 中已正式支持全局异常处理机制。
相关问题
- 如何将 .NET MAUI 异常日志保存到本地文件?
- 在 Android/iOS 上捕获原生崩溃有哪些方案?
- .NET MAUI 的异常处理机制与 Xamarin.Forms 有何区别?