MAUI Community Toolkit关闭Popup时触发空引用异常求助
问题重现
在MAUI应用中使用CommunityToolkit.Maui的Popup实现加载提示,在页面OnAppearing方法中显示弹窗、执行异步初始化后关闭,触发空引用异常:
Object reference not set to an instance of an object.
at CommunityToolkit.Maui.Views.Popup.CommunityToolkit.Maui.Core.IPopup.OnClosed(Object result)
at CommunityToolkit.Maui.Views.Popup.d__62.MoveNext()
at CommunityToolkit.Maui.Views.Popup.d__60.MoveNext()
at LanguageInUse.Views.DictionaryList.d__3.MoveNext() in C:\Projects\ERDevOps\LIUApp\LanguageInUse\Views\DictionaryList.xaml.cs:line 32
弹窗已正常实例化,但关闭时仍报错。
解决方案
1. 改用Loaded事件替代OnAppearing
OnAppearing触发时机早于页面完全渲染完成,此时弹窗可能尚未完成内部初始化。改用页面的Loaded事件,确保UI元素都已就绪:
public DictionaryList() { InitializeComponent(); Loaded += OnPageLoaded; } private async void OnPageLoaded(object sender, EventArgs e) { var popup = new LoadingPopup(); this.ShowPopup(popup); await vm.Init(); // 先判断弹窗是否处于打开状态再关闭 if (popup.IsOpen) { await popup.CloseAsync(); } }
2. 升级CommunityToolkit.Maui到最新稳定版
旧版本的CommunityToolkit.Maui存在Popup关闭时的空引用bug,已在后续版本修复。打开NuGet包管理器,将CommunityToolkit.Maui更新至当前最新稳定版(如8.0.0及以上)。
3. 通过Dispatcher调度关闭操作
确保关闭弹窗的操作在正确的UI线程上下文执行,避免因线程调度问题导致内部引用为空:
protected override async void OnAppearing() { base.OnAppearing(); var popup = new LoadingPopup(); this.ShowPopup(popup); await vm.Init(); // 用Dispatcher确保UI线程执行关闭操作 await Dispatcher.DispatchAsync(async () => { if (popup != null && popup.IsOpen) { await popup.CloseAsync(); } }); }
4. 封装异步初始化逻辑(避免async void风险)
async void的生命周期方法异常难以捕获,可将初始化逻辑封装为独立异步方法:
protected override async void OnAppearing() { base.OnAppearing(); await InitializeDataAsync(); } private async Task InitializeDataAsync() { var popup = new LoadingPopup(); this.ShowPopup(popup); try { await vm.Init(); } finally { if (popup.IsOpen) { await popup.CloseAsync(); } } }
内容的提问来源于stack exchange,提问作者Enrico

