.NET MAUI点击按钮弹出模态等待页,阻塞执行等待用户响应问题
解决方案
核心思路是利用TaskCompletionSource实现模态页面的结果回调,同时通过异步等待让UI线程及时渲染新页面,阻塞当前流程直到用户做出选择。
步骤1:改造自定义模态页面(NewPage1)
给页面添加TaskCompletionSource<bool>来传递用户选择的结果,按钮点击时设置结果并关闭页面:
public partial class NewPage1 : ContentPage { private readonly TaskCompletionSource<bool> _taskCompletionSource; public NewPage1(TaskCompletionSource<bool> taskCompletionSource) { InitializeComponent(); _taskCompletionSource = taskCompletionSource; } // OK按钮点击事件 private void OkBtn_Clicked(object sender, EventArgs e) { _taskCompletionSource.SetResult(true); _ = Navigation.PopModalAsync(); } // CANCEL按钮点击事件 private void CancelBtn_Clicked(object sender, EventArgs e) { _taskCompletionSource.SetResult(false); _ = Navigation.PopModalAsync(); } // 防止页面意外关闭导致任务无限等待 protected override void OnDisappearing() { base.OnDisappearing(); if (!_taskCompletionSource.Task.IsCompleted) { _taskCompletionSource.SetResult(false); } } }
步骤2:修改Button1的点击事件
将点击事件改为异步方法,通过TaskCompletionSource等待用户操作结果,实现流程阻塞:
private async void Button1_Clicked(object sender, EventArgs e) { var tcs = new TaskCompletionSource<bool>(); // 弹出模态页面,传入TaskCompletionSource await Application.Current.MainPage.Navigation.PushModalAsync(new NewPage1(tcs)); // 等待用户选择结果,此处会暂停当前流程直到用户操作完成 bool isOkSelected = await tcs.Task; // 根据用户选择执行后续逻辑 if (isOkSelected) { // 用户点击OK,继续原业务流程 // 示例:执行你的核心业务代码 } else { // 用户点击CANCEL或关闭页面,执行备选逻辑 } }
为什么之前的方法无效?
PushModalAsync是异步方法,若不使用await,UI线程会优先执行完Button1点击事件的剩余代码,才会处理新页面的渲染,导致页面延迟显示。Task.Run或Dispatcher.Dispatch会将操作放到后台线程或调度队列,反而会让UI渲染被延后,无法解决问题。
内容的提问来源于stack exchange,提问作者Rodrigo
相关产品推荐
相关产品推荐

