xamarin用await /异步形式更新UI

问题描述:

我正在用Visual Studio for Mac写一个非常基本的Xamarin Forms应用程序。 此应用程序应与Android和iOS上的PCL一起使用。xamarin用await /异步形式更新UI

我在XAML文件上有一个空的TableView。我想要做的是填充这个TableView与我将从Web服务中获取的数据。

这里是我的C#代码:

HttpClient client = new HttpClient(); 

public async Task<List<MyItem>> LoadData() 
{ 
    try 
    { 
     var response = await client.GetAsync(new Uri("http://example.com/myservice.php")); 
     if (response.IsSuccessStatusCode) 
     { 
      var content = await response.Content.ReadAsStringAsync(); 
      return JsonConvert.DeserializeObject<List<MyItem>>(content); 
     } 
    } 
    catch (Exception) 
    { 
     return null; 
    } 

    return null; 
} 

async void Handle_Clicked(object sender, System.EventArgs e) 
{ 
    activity_indicator.IsRunning = true; 
    var data = await LoadData(); 
    activity_indicator.IsRunning = false; 

    mylistview.Root.Clear(); 
    foreach (var item in data) 
    { 
     TableSection section = new TableSection() { Title = item.GroupTitle }; 
     foreach (var subitem in item.subitems) 
     { 
      var cell = new TextCell() { Text = subitem.Title }; 
      cell.Tapped += on_item_tapped; 
      section.Add(cell); 
     } 
     mylistview.Root.Add(section); 
    } 
} 

我是新来的等待和异步编程。我曾经用iOS代表开发原生iOS应用程序。我听说一个线程无法更新UI:例如,我可以在LoadData()方法中进行一些UI更新吗? 所以我想知道如果我的代码是好的。 它看起来很好,因为它的工作原理,但我想知道这是否是一件好事,这样工作?

+0

使用'异步/ await'这里是正确的选择。当你看到异步调用完成后,UI线程上的await会捕获当前上下文,并在该上下文中恢复,这使得在调用完成之后更新UI。我建议的一个建议是将'Handle_Clicked'中的代码分解为一个项目模板,但与'async'无关。 – JSteward

+0

当主线程等待await指令时,您是否认为UI是被动的? – Bob5421

+0

@ Bob5421运行代码并亲自查看。 – Servy

private void UpdateUI(Action action) 
{ 
    this.Invoke(new Action(action), null); 
} 

用法:UpdateUI((=)lable1.Text =“Updated”);

+0

此代码在Xamarin Forms中无效,也许您正在考虑WinForms和IsInvokeRequired? – JSteward

+0

你的意思是如果我更新异步方法中的UI控件,我需要使用此Invoke调用? – Bob5421

+0

@ Bob5421不,你不知道。 – Servy

我相信它

Device.BeginInvokeOnMainThread(() => 
{ 

});