我正在努力与Xamarin快速合并一个基本的移动应用程序来打击本地API。我在VS2015中创建了一个默认的Xamarin.Forms PCL项目,并尝试添加代码来命中我在本地运行的API。但是,当我到达行var response = await client.GetAsync(uri)时,代码执行并立即跳转到RefreshDataAsync()之后的行,从而绕过半个函数,包括catch和finally块的try /抓住声明。我已经尽力为应用程序中的每一行添加断点,并且100%不会在等待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!");
}
}
}
}
答案 0 :(得分: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来重构代码,但这不是您的问题。