【MAUI】在 .NET MAUI 中实现全局异常捕获的完整指南

发布于:2025-08-15 ⋅ 阅读:(17) ⋅ 点赞:(0)


在这里插入图片描述

.NET MAUI 是 .NET 跨平台原生 UI 的未来,将成为 .NET的一部分… 在 .NET MAUI 开发中,全局异常捕获是提升应用稳定性的关键。以下基于 .NET MAUI 官方实践,提供完整实现方案:


一、核心方法

通过重写 Application 类方法实现跨平台异常捕获:

// 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
    }
}

二、平台适配技巧
  1. Android 特殊处理
    Platforms/Android/MainApplication.cs 添加:

    AndroidEnvironment.UnhandledExceptionRaiser += (sender, args) => 
    {
        Console.WriteLine($"Android 环境异常: {args.Exception}");
        args.Handled = true; // 阻止应用崩溃
    };
    
  2. iOS/macOS 优化
    通过 NSSetUncaughtExceptionHandler 捕获原生异常:

    #if IOS || MACCATALYST
    ObjCRuntime.Runtime.MarshalManagedException += (_, e) => 
    {
        Console.WriteLine($"Apple 平台异常: {e.Exception}");
        e.ExceptionMode = ObjCRuntime.MarshalManagedExceptionMode.Disable;
    };
    #endif
    
  3. Windows

#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

三、进阶实践
  1. 与日志系统集成
    结合 Microsoft.Extensions.Logging 记录异常:

    private void HandleException(Exception ex)
    {
        var logger = Handler.MauiContext.Services.GetService<ILogger<App>>();
        logger?.LogError(ex, "全局异常捕获");
    }
    
  2. 错误上报服务
    异步上报到后端:

    _ = Task.Run(async () => 
    {
        await MyErrorReportingService.ReportAsync(ex);
    });
    
  3. 用户友好提示
    在主线程显示弹窗:

    MainThread.BeginInvokeOnMainThread(() => 
    {
        MainPage?.DisplayAlert("系统错误", "已记录问题,请重试", "确定");
    });
    

四、注意事项
  1. 作用范围

    • OnUnhandledException:捕获 UI 线程异常
    • AppDomain.UnhandledException:捕获后台线程异常
    • 无法捕获原生崩溃(需平台特定工具)
  2. 调试模式差异
    DEBUG 环境下建议显示详细错误,RELEASE 下隐藏技术细节:

    #if RELEASE
    string message = "操作失败,请联系支持";
    #else
    string message = ex.ToString();
    #endif
    
  3. 性能影响
    避免在异常处理器中执行耗时操作,建议异步处理日志/上报逻辑。

参考官方路线图:.NET MAUI 在 .NET 7 中已正式支持全局异常处理机制。


相关问题

  1. 如何将 .NET MAUI 异常日志保存到本地文件?
  2. 在 Android/iOS 上捕获原生崩溃有哪些方案?
  3. .NET MAUI 的异常处理机制与 Xamarin.Forms 有何区别?

网站公告

今日签到

点亮在社区的每一天
去签到