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
相关产品推荐
相关产品推荐

