2017-01-27 23 views
1

我试图快速将Xamarin基本的移动应用程序一起打到本地API。我在VS2015中创建了一个默认的Xamarin.Forms PCL项目,并试图添加代码来创建我在本地运行的API。但是,当我到达var response = await client.GetAsync(uri)行时,代码将执行并立即跳回到RefreshDataAsync()之后的行,从而绕过半个函数,包括catch和try/catch语句。我已经尽可能在应用程序的每一行添加断点,并且它100%不会在await GetAsync调用之外调用任何代码。代码在等待呼叫后跳回到调用函数

几小时后,我不得不承认我对这个应用程序发生了什么事情感到不知所措,因为我之前从来没有遇到过await/async问题。

using Newtonsoft.Json; 
using System; 
using System.Collections.Generic; 
using System.Diagnostics; 
using System.Net.Http; 
using Xamarin.Forms; 

namespace consumerestful 
{ 
    public class App : Application 
    { 
    private List<Person> people; 

    public App() 
    { 
     // The root page of your application 
     RefreshDataAsync(); 
     var test = people; 

     var content = new ContentPage 
     { 
      Title = "consumerestful", 
      Content = new StackLayout 
      { 
       VerticalOptions = LayoutOptions.Center, 
       Children = { 
        new Label { 
         HorizontalTextAlignment = TextAlignment.Center, 
         Text = "Welcome to Xamarin Forms!", 
        } 
       } 
      } 
     }; 

     MainPage = new NavigationPage(content); 
    } 

    protected override void OnStart() 
    { 
     // Handle when your app starts 
    } 

    protected override void OnSleep() 
    { 
     // Handle when your app sleeps 
    } 

    protected override void OnResume() 
    { 
     // Handle when your app resumes 
    } 

    public async void RefreshDataAsync() 
    { 
     HttpClient client; 
     client = new HttpClient(); 
     client.MaxResponseContentBufferSize = 256000; 

     //RestUrl = http://127.0.0.1:5000/api/ 
     var uri = new Uri(Constants.RestUrl); 
     try 
     {     
      var response = await client.GetAsync(uri);//problem line 
      //nothing after the above line runs. It jumps back to Line 19(var test = people) 

      var test = response; 

      if (response.IsSuccessStatusCode) 
      { 
       var content = await response.Content.ReadAsStringAsync(); 
       people = JsonConvert.DeserializeObject<List<Person>>(content); 
      } 
     } 
     catch (Exception ex) 
     { 
      Debug.WriteLine(@"    ERROR {0}", ex.Message); 
     } 
     finally 
     { 
      Debug.WriteLine(@"    Finally Block Ran!"); 
     } 
    } 
    } 
} 

回答

1

函数RefreshDataAsync()是您定义的异步函数。但是当你在构造函数中调用它时,不能用await调用它,因为构造函数调用不是异步的。因此,你调用了你展示的方式,并且因为这样,调用没有被等待,程序的执行流程在该调用完成之前继续。

所以刷新数据的正确方法是使用OnAppearing()中的await关键字调用RefreshDataAsync(),并使用async标记OnAppearing。请注意,Intellisense可能会抱怨说您应该返回Task,但是您不能这么做,因为这不是基类中定义的内容。所以我认为你可以将其视为无效。以下是如何将您的代码更改为:

public App() 
{ 
    var content = new ContentPage 
    { 
     Title = "consumerestful", 
     Content = new StackLayout 
     { 
      VerticalOptions = LayoutOptions.Center, 
      Children = { 
       new Label { 
        HorizontalTextAlignment = TextAlignment.Center, 
        Text = "Welcome to Xamarin Forms!", 
       } 
      } 
     } 
    }; 

    MainPage = new NavigationPage(content); 
} 

public async override void OnAppearing() 
{ 
    // The root page of your application 
    await RefreshDataAsync(); 
    var test = people; 
} 

只是在这里的建议。您可能还想通过移动try catch来重构代码,但这不是您问题的要点。

+0

嘿谢谢。雅的代码现在只是黑客入侵。我计划在其它应用程序运行后正确实施它。我无法重写OnAppearing方法,因为我得到一个错误,说它不存在。但是,如果我按照你所说的做,但在OnStart中,它就可以工作。当然,我得到了一个不同的错误,但你的答案似乎解决了我的问题。 我已经标记了你的答案,但如果你能告诉我为什么我没有OnAppearing方法,或者如果你可以改变你的方法到OnStart,这可能会更好的未来观众。 – xCasper