我正在使用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
从不显示,该应用程序挂着等待答案(我想)。
如果有人能解释如何解决这个问题,我将不胜感激,但是如果他们能解释为什么会发生这种情况,那会更好。
>答案 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线程上继续执行