重点是你想要异步操作,你需要等待不会发生在UI线程。尤里的解决方案是这样做的,但是你也可以做你的异步操作,然后如果你需要对UI进行任何更新,你只需要在UI线程上发生,以防止UI被锁定。
真正的问题来自您的线程如何工作。如果你想看到这个实时,请拉开Xamarin Stud中的线程调试板,并在你逐步执行代码时观察线程。
让我们把你的代码为例:
private void Button_Clicked(object sender, EventArgs e)
{
var btn = (Button)sender;
btn.Text = "Wait";
...
当我们进入“Button_Clicked”事件处理程序,我们现在都在UI线程。我们怎么知道?因为用户点击了按钮,我们在这里。一切都在主UI线程上运行。无论我们下一步在代码中做什么,都会继续在该线程上运行,除非操作系统确定需要管理线程(性能,操作系统的工作原理等)。
如果您的某些代码执行一些异步任务,例如发送Web请求调用以从REST API获取某些数据,则需要了解您所在的线程。我们无法保证我们的网络请求调用将在UI线程或任何线程上运行,而无需手动处理。这是我们高级操作系统的优势,它为我们处理了多核多线程处理。
因此,我们希望确保在UI线程上发生UI的任何更新。正确的解决方案,你的代码将低于:
private async void Btn1_Clicked(object sender, EventArgs e)
{
var btn = (Button)sender;
btn.Text = "Wait";
...some code...maybe async or not (take out async above if not)
Device.BeginInvokeOnMainThread(() =>
{
btn.Text = "Do Something";
});
}
这适用于我们,因为我们告诉Xamarin.Forms到主线程中运行该命令。 Xamarin.Forms以这种方式公开主UI-Thread。另一种选择是采用UI-Thread的上下文,并在进行更新时缓存它。这通常在Xamarin.Android和Xamarin.iOS应用程序中完成。
完成这一切的真正方法是通过数据绑定。 Xamarin.Forms是为了与Model-View-ViewModel(MVVM)模式一起使用而构建的。当您拨打OnPropertyChanged
时,Xamarin.Forms绑定会为您处理所有上下文切换。这样你就可以更新绑定到你的按钮文本的ViewModel中的属性。
我希望这可以帮助您更好地理解线程级别正在发生的事情!
披露:我对Xamarin /微软工作
UI线程被阻塞你的代码执行。您需要修改单独线程中的Button文本 –
感谢您的信息Sandeep! –