第二个 DisplayAlert 挂起

Second DisplayAlert hanging

我正在使用 Xamarin Forms 构建应用程序,我遇到了 DisplayAlert 触发一次但第二次挂起的问题。

请考虑以下代码:

ThisThingClickedCommand = new Command(
async () =>
{
    var continue = true;
    if (SomeVariable.is_flagged == 0)
    {
        continue = await PageSent.DisplayAlert("User Question", "This is a question for the user", "Yes", "No");
    }

    if (continue)
    {
        Debug.WriteLine("This debug fires");
        var AnswerToSecondQuestion = await PageSent.DisplayAlert("Second Question", "This is a second question for the user", "Yes", "No");
        if (AnswerToSecondQuestion)
        {
            // Do more things
        }
        Debug.WriteLine("This one does not :(");
    }
}),

上面的代码已经在项目中使用了很长时间并且似乎一直有效,直到最近更新到 Visual Studio 2017 以及随后 Windows 的一些新目标版本。

当我在 Windows 上启动该应用程序(目前尚未在其他设备上测试)并且这段代码运行时,第一个 DisplayAlert 显示没有问题,但是第二个 DisplayAlert 从不显示并且应用程序挂起等待它的回答(我假设)。

如果有人能解释如何解决这个问题,我将不胜感激,但如果他们能解释为什么也会发生这种情况, 这样就更好了

使用Device.BeginInvokeOnMainThread确保UI线程处理第二次调用:

     ThisThingClickedCommand = new Command(
    async ()=>
    {
        var continue = true;
        if (SomeVariable.is_flagged == 0)
        {
            continue = await PageSent.DisplayAlert("User Question", "This is a question for the user", "Yes", "No");
        }

        if (continue)
        {
            Debug.WriteLine("This debug fires");

Device.BeginInvokeOnMainThread(async () =>
            var AnswerToSecondQuestion = await PageSent.DisplayAlert("Second Question", "This is a second question for the user", "Yes", "No");
            if (AnswerToSecondQuestion)
            {
                // Do more things
            }
            Debug.WriteLine("This one does not :(");
        });
    }),

确实,在等待之后,如果您想操纵 UI

的方法或属性,您需要确保在 UI 线程上继续执行

避免async void 触发后忘记方法,这是命令操作委托将转换成的方法。一个例外是事件处理程序。

引用Async/Await - Best Practices in Asynchronous Programming

创建事件和处理程序

private event EventHandler raiseAlerts = delegate { };
private async void OnRaiseAlerts(object sender, EventArgs args) {
    var _continue = true;
    if (SomeVariable.is_flagged == 0) {
        _continue = await PageSent.DisplayAlert("User Question", "This is a question for the user", "Yes", "No");
    }

    if (_continue) {
        Debug.WriteLine("This debug fires");
        var AnswerToSecondQuestion = await PageSent.DisplayAlert("Second Question", "This is a second question for the user", "Yes", "No");
        if (AnswerToSecondQuestion) {
            // Do more things
        }
        Debug.WriteLine("This one does not :(");
    }
}

订阅活动。最有可能在构造函数中

raiseAlerts += OnRaiseAlerts

并在命令动作委托中引发事件

ThisThingClickedCommand = new Command(() => raiseAlerts(this, EventArgs.Empty));

至少现在应该能够捕获任何抛出的异常,以了解存在的问题(如果有的话)。