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

基于Popup插件的DialogsService回调结果获取实现是否正确?

问题:弹窗服务的回调结果返回逻辑是否正确?

我正在使用一款弹窗页面插件,原有使用代码如下:

var confirm = new AlertDialog(new AlertSettings() { Title = "Confim Title", Message = "Confirm Question?"});
confirm.Callback += (result) => { if (result) { // do something } };
await PopupNavigation.PushAsync(confirm);

我尝试编写一个服务以获取bool类型的回调结果,相关代码如下:

public interface IDialogsService {
    Task<bool> DisplayConfirmAsync(string title, string message);
}
public class DialogsService : IDialogsService {
    public DialogsService() { }
    public async Task<bool> DisplayConfirmAsync(string title, string message) {
        bool tresult = false;
        var confirm = new AlertDialog(new AlertSettings() { Title = title, Message = message});
        confirm.Callback += (result) => { tresult = (bool)result; };
        await PopupNavigation.Instance.PushAsync(confirm);
        return tresult;
    }
}

调用方式为:

bool result = await DialogsService.DisplayConfirmAsync("Confim Title", "Confirm Question?");

请问上述实现方式是否正确?


回答

你的实现不正确,核心问题在于 PopupNavigation.PushAsync 的行为:它只是将弹窗推入导航栈并完成显示动作,并不会等待用户完成交互(点击确认/取消按钮)就继续执行后续代码。因此你返回的 tresult 始终是初始化的 false,根本无法拿到用户的真实选择结果。

问题根源拆解

当你执行 await PopupNavigation.Instance.PushAsync(confirm); 时,await 仅等待弹窗完成"推入导航栈并显示"这个操作,而不是等待用户关闭弹窗。代码会立刻跳到 return tresult; 这一行,此时用户还未触发任何按钮点击,Callback 委托完全没被执行,tresult 自然还是初始值。

正确实现方式

我们可以用 TaskCompletionSource<bool> 来创建一个可手动完成的任务,等待弹窗的回调触发后再返回结果:

public class DialogsService : IDialogsService {
    public async Task<bool> DisplayConfirmAsync(string title, string message) {
        // 创建TaskCompletionSource,用于等待用户交互结果
        var taskCompletionSource = new TaskCompletionSource<bool>();
        
        var confirm = new AlertDialog(new AlertSettings() { Title = title, Message = message});
        confirm.Callback += (result) => {
            // 用户做出选择后,设置任务的结果
            taskCompletionSource.SetResult((bool)result);
            // 根据插件特性,可能需要手动关闭弹窗(若插件不自动处理)
            _ = PopupNavigation.Instance.PopAsync();
        };
        
        await PopupNavigation.Instance.PushAsync(confirm);
        
        // 等待用户的选择结果完成后再返回
        return await taskCompletionSource.Task;
    }
}

额外注意事项

  1. 关闭弹窗:部分弹窗插件在用户点击按钮后会自动关闭弹窗,如果你的插件没有这个特性,一定要在回调里调用 PopupNavigation.Instance.PopAsync(),否则弹窗会一直停留在界面上。
  2. 调用方式修正:你原来的调用代码 DialogsService.DisplayConfirmAsync 是静态调用,但你的 DisplayConfirmAsync 是实例方法,实际使用时需要先实例化 DialogsService(或通过依赖注入获取实例):
    // 示例:实例化服务后调用
    var dialogsService = new DialogsService();
    bool result = await dialogsService.DisplayConfirmAsync("Confirm Title", "Confirm Question?");
    

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.07 22:12:51