作者:仲颖凯翰奕颖 | 来源:互联网 | 2023-01-28 17:47
C#用户界面更新不确定UWP应用程序,C#,VisualStudio2017,Windows10CreatorsUpdate(10.0;Build15063)。我们将TextBlo
C#用户界面更新不确定
UWP应用程序,C#,Visual Studio 2017,Windows 10 Creators Update(10.0; Build 15063)。
我们将TextBlock1称为T1,将TextBlock2称为T2 …所需的输出是:
T1显示“工作已开始”。
T2显示“第1步”
T2显示“第2步”
T2显示“”
T1显示“完成工作”。
private async void Btn_Click(object sender, RoutedEventArgs e) { TextBlock1.Text = "Work started."; await DoWork(); TextBlock1.Text = "Work done."; } private async Task DoWork() { TextBlock2.Text = "Step 1"; await Task.Delay(1); //Pretend to do something TextBlock2.Text = "Step 2"; await Task.Delay(1); //Pretend to do something TextBlock2.Text = ""; }
当我调试时,实际输出是不确定的:
1:TextBlock更新仅在我进入await或事件处理程序关闭时发生。
2:有时TextBlock更新发生在等待#1,有时等待#2,有时两者都有,有时两者都没有。
3:无论先前的事件如何,T1都会显示“已完成工作”。 和T2将在Btn_Click()的末尾显示“”。
当我请求UI更新时,我希望程序除了执行更新所需的操作外什么都不做。 在UI上显示更新之前,它不应该继续我的下一个请求。
我花了好几天时间。 可能吗?
我找到了一种方法来消除这个问题的非确定性方面。 但我真的不明白发生了什么,它仍然不符合上面的粗体要求:
private async Task UpdateTextInUI(TextBlock textBlock, string str) { await textBlock.Dispatcher.RunAsync(CoreDispatcherPriority.Normal, new DispatchedHandler(() => { textBlock.Text = str; })); }
让我为你分解一下:
-
TextBlock更新仅在我进入await或事件处理程序关闭时发生。
这是完全正常的。 await调用基本上会做下一件事:启动给定的函数,直到它正在继续返回被调用者。 这也意味着,当您等待的函数返回时,范围将在await之后立即返回。 因此,如果等待的function非常快,那么UI可能没有足够的时间来应用您的更改。
-
有时TextBlock更新发生在等待#1,有时等待#2,有时两者都有,有时两者都没有。
与上面相同,有时UI有足够的时间,有时则没有。 线程很有趣。 它们是非确定性的。
-
无论以前的事件如何,T1都会显示“已完成工作”。 和T2将在Btn_Click()的末尾显示“”。
在DoWorkfunction完成后,UI将获得完全控制权,因此它可以应用所有更改 – >最后应用的文本值。
编辑:
如果您真的想要更新UI,可以await Task.Yield()
。 这将迫使UI获得后退控制权。
上述就是C#学习教程:C#用户界面更新不确定分享的全部内容,如果对大家有所用处且需要了解更多关于C#学习教程,希望大家多多关注—编程笔记