重點是你想要異步操作,你需要等待不會發生在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! –