You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

MAUI应用全局错误处理存疑:弹窗异常与可靠退出求助

MAUI全局错误处理(Windows/Android):弹窗展示与可靠退出

一、全局异常捕获配置

MAUI的跨平台异常捕获逻辑和Xamarin存在差异,不能仅依赖AppDomain.CurrentDomain.UnhandledException,需要针对Windows和Android分别配置平台专属的异常处理器:

Windows平台

在Platforms/Windows/App.xaml.cs的OnLaunched方法中,注册两个关键异常事件,覆盖UI线程和非UI线程的未处理异常:

protected override void OnLaunched(LaunchActivatedEventArgs args)
{
    base.OnLaunched(args);

    // 处理UI线程未捕获异常
    Microsoft.UI.Xaml.Window.Current.Dispatcher.UnhandledException += Dispatcher_UnhandledException;
    // 处理非UI线程未捕获异常
    AppDomain.CurrentDomain.UnhandledException += CurrentDomain_UnhandledException;
}

Android平台

在Platforms/Android/MainApplication.cs中,注册全局未捕获异常处理器:

public override void OnCreate()
{
    base.OnCreate();
    Android.Runtime.AndroidEnvironment.UnhandledExceptionRaiser += AndroidEnvironment_UnhandledExceptionRaiser;
}

二、错误详情弹窗展示(避免无效句柄异常)

Windows平台:用ContentDialog替代MessageDialog

直接使用MessageDialog会因异常发生时窗口状态不稳定导致无效句柄错误,改用WinUI3的ContentDialog,并通过UI线程调度器执行:

private async void Dispatcher_UnhandledException(object sender, Microsoft.UI.Xaml.DispatcherUnhandledExceptionEventArgs e)
{
    e.Handled = true;
    await ShowErrorDialog(e.Exception.Message + "\n\n" + e.Exception.StackTrace);
    ExitApp();
}

private async void CurrentDomain_UnhandledException(object sender, UnhandledExceptionEventArgs e)
{
    var ex = e.ExceptionObject as Exception;
    await Microsoft.UI.Xaml.Window.Current.Dispatcher.RunAsync(Microsoft.UI.Xaml.CoreDispatcherPriority.Normal, 
        async () => await ShowErrorDialog(ex.Message + "\n\n" + ex.StackTrace));
    ExitApp();
}

private async Task ShowErrorDialog(string message)
{
    var dialog = new ContentDialog
    {
        Title = "应用错误",
        Content = message,
        CloseButtonText = "退出",
        XamlRoot = Microsoft.UI.Xaml.Window.Current.Content.XamlRoot
    };
    await dialog.ShowAsync();
}

Android平台:用AlertDialog在UI线程展示

通过MainThread确保弹窗在UI线程执行,避免线程安全问题:

private void AndroidEnvironment_UnhandledExceptionRaiser(object sender, Android.Runtime.UnhandledExceptionEventArgs e)
{
    e.Handled = true;
    var ex = e.Exception;
    MainThread.BeginInvokeOnMainThread(() =>
    {
        var alert = new AlertDialog.Builder(Platform.CurrentActivity)
            .SetTitle("应用错误")
            .SetMessage(ex.Message + "\n\n" + ex.StackTrace)
            .SetPositiveButton("退出", (s, args) => ExitApp())
            .Create();
        alert.Show();
    });
}

三、可靠退出应用

针对两个平台分别实现符合平台规范的退出逻辑:

private void ExitApp()
{
#if WINDOWS
    Microsoft.UI.Xaml.Application.Current.Exit();
#elif ANDROID
    Platform.CurrentActivity.FinishAffinity();
    Android.OS.Process.KillProcess(Android.OS.Process.MyPid());
#endif
}

注意事项

  • Android平台需确保Platform.CurrentActivity可用,MAUI默认已完成初始化,无需额外配置。
  • 非UI线程触发的异常必须通过UI线程调度器执行弹窗操作,否则会引发线程安全问题。

内容的提问来源于stack exchange,提问作者Sparky

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.17 01:26:17