第二次DisplayAlert挂起

时间:2018-06-26 10:30:14

标签: c# xamarin.forms uwp async-await xamarin.uwp

我正在使用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从不显示,该应用程序挂着等待答案(我想)。

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

>

2 个答案:

答案 0 :(得分:2)

避免使用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));

至少现在应该能够捕获所有引发的异常,以了解存在什么问题。

答案 1 :(得分:1)

使用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线程上继续执行