.NET MAUI Shell异步调用GoToAsync导航报强制转换无效异常
.NET MAUI Shell 导航异常问题
问题复现场景
在ContentPage页面编写如下按钮点击事件代码:
private async void Button_Clicked(object sender, EventArgs e) { await Shell.Current.GoToAsync(".."); }
点击按钮执行时抛出如下异常:
System.InvalidCastException: 'Specified cast is not valid.'
如果移除代码中的async和await关键字,改为同步执行导航返回MainPage,流程完全正常,不会触发异常。
异常堆栈跟踪
0xFFFFFFFFFFFFFFFF in Android.Runtime.JNIEnv.monodroid_debugger_unhandled_exception C# 0x14 in Android.Runtime.JNINativeWrapper._unhandled_exception at /Users/runner/work/1/s/xamarin-android/src/Mono.Android/Android.Runtime/JNINativeWrapper.g.cs:12,5 C# 0x1D in Android.Runtime.JNINativeWrapper.Wrap_JniMarshal_PP_V at /Users/runner/work/1/s/xamarin-android/src/Mono.Android/Android.Runtime/JNINativeWrapper.g.cs:23,26 C# 0x17 in System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw C# 0x6 in System.Threading.Tasks.Task.<>c.<ThrowAsync>b__128_0 C# 0xC in Android.App.SyncContext. at /Users/runner/work/1/s/xamarin-android/src/Mono.Android/Android.App/SyncContext.cs:36,19 C# 0xE in Java.Lang.Thread.RunnableImplementor.Run at /Users/runner/work/1/s/xamarin-android/src/Mono.Android/Java.Lang/Thread.cs:36,6 C# 0x8 in Java.Lang.IRunnableInvoker.n_Run at /Users/runner/work/1/s/xamarin-android/src/Mono.Android/obj/Release/net6.0/android-32/mcw/Java.Lang.IRunnable.cs:84,4 C# 0x8 in Android.Runtime.JNINativeWrapper.Wrap_JniMarshal_PP_V at /Users/runner/work/1/s/xamarin-android/src/Mono.Android/Android.Runtime/JNINativeWrapper.g.cs:22,5 C#
问题产生原因
这是.NET MAUI 早期版本在Android平台的已知框架Bug:异步执行Shell返回导航时,页面出栈销毁流程和异步任务的回调线程调度存在时序冲突。GoToAsync异步执行触发当前页面从导航栈移除后,事件回调尝试回到已被回收销毁的页面视图上下文,运行时对已释放的控件对象做类型转换时就会抛出无效强制转换异常。
同步执行导航时,整个导航出栈流程在当前UI线程同步完成,不会触发异步回调回到已销毁页面的逻辑,因此不会报错。
修复方法
- 优先升级.NET MAUI到最新的稳定发行版本,该类型转换时序冲突的Bug已经在后续官方服务更新中被修复。
- 若暂时无法升级框架版本,可以在页面的
OnDisappearing生命周期方法中取消页面内所有未完成的异步任务,或者在触发导航前手动解绑对应按钮的点击事件,避免异步回调访问已被销毁的页面对象。 - 临时兼容写法可将导航操作投递到UI线程队列末尾执行,错开页面销毁和异步回调的执行时机,参考代码如下:
private async void Button_Clicked(object sender, EventArgs e) { await Dispatcher.DispatchAsync(async () => { await Shell.Current.GoToAsync(".."); }); }
内容的提问来源于stack exchange,提问作者jmdess
相关产品推荐
相关产品推荐

