C# 等待调用后,代码跳回调用函数
我正在尝试用Xamarin快速破解一个基本的移动应用程序,以实现本地API。我在VS2015中创建了一个默认的Xamarin.Forms PCL项目,并尝试添加代码以命中我在本地运行的API。但是,当我到达var response=await client.GetAsync(uri)行时,代码执行并在RefreshDataAsync()之后立即跳回该行,从而绕过了半个函数,包括try/catch语句的catch和finally块。我甚至在应用程序中的每一行都添加了断点,它100%不会调用wait-GetAsync调用之外的任何代码 几个小时后,我不得不承认我对这个应用程序到底发生了什么感到困惑,因为我以前从未遇到过wait/async的问题C# 等待调用后,代码跳回调用函数,c#,asynchronous,xamarin,async-await,xamarin.forms,C#,Asynchronous,Xamarin,Async Await,Xamarin.forms,我正在尝试用Xamarin快速破解一个基本的移动应用程序,以实现本地API。我在VS2015中创建了一个默认的Xamarin.Forms PCL项目,并尝试添加代码以命中我在本地运行的API。但是,当我到达var response=await client.GetAsync(uri)行时,代码执行并在RefreshDataAsync()之后立即跳回该行,从而绕过了半个函数,包括try/catch语句的catch和finally块。我甚至在应用程序中的每一行都添加了断点,它100%不会调用wait
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!");
}
}
}
}
使用Newtonsoft.Json;
使用制度;
使用System.Collections.Generic;
使用系统诊断;
使用System.Net.Http;
使用Xamarin.Forms;
命名空间消费型
{
公共类应用程序:应用程序
{
私人名单;
公共应用程序()
{
//应用程序的根页面
RefreshDataAsync();
var检验=人;
var content=newcontentpage
{
Title=“消费主义”,
内容=新的堆栈布局
{
垂直选项=布局选项。中心,
儿童={
新标签{
HorizontalTextAlignment=TextAlignment.Center,
Text=“欢迎使用Xamarin表单!”,
}
}
}
};
主页=新导航页面(内容);
}
受保护的覆盖void OnStart()
{
//在应用程序启动时处理
}
受保护的覆盖void OnSleep()
{
//在应用程序睡眠时处理
}
受保护的覆盖void OnResume()
{
//在应用程序恢复时处理
}
公共异步void RefreshDataAsync()
{
HttpClient;
client=新的HttpClient();
client.MaxResponseContentBufferSize=256000;
//RestUrl=http://127.0.0.1:5000/api/
var uri=新的uri(Constants.RestUrl);
尝试
{
var response=wait client.GetAsync(uri);//问题行
//上面的行运行后没有任何内容。它跳回第19行(var test=people)
var测试=响应;
if(响应。IsSuccessStatusCode)
{
var content=await response.content.ReadAsStringAsync();
people=JsonConvert.DeserializeObject(内容);
}
}
捕获(例外情况除外)
{
WriteLine(@“ERROR{0}”,例如Message);
}
最后
{
WriteLine(@“最后阻塞运行!”);
}
}
}
}
函数RefreshDataAsync()是您定义的异步函数。但是,当您在构造函数中调用它时,不能使用wait调用它,因为构造函数调用不是异步的。因此,您调用了所显示的方式,因为这样,调用不会被等待,程序的执行流会在调用完成之前继续
因此,刷新数据的正确方法是在OnAppearing()中使用wait关键字调用RefreshDataAsync(),并使用async标记OnAppearing。请注意,Intellisense可能会抱怨您应该返回任务,但您也不能这样做,因为这不是基类中定义的。所以我认为你可以把它当作空白。以下是如何将代码更改为:
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来重新构造代码,但这不是问题的重点。嘿,谢谢。是的,现在代码刚刚被破解了。我计划在它运行后在另一个应用程序中正确地实现它。我无法重写OnAppearing方法,因为我收到一个错误,说它不存在。但如果我照你说的做,但在OnStart中,它会起作用。虽然我有不同的错误,但你的回答似乎解决了我的问题。我已经将你的标记为答案,但是如果你能告诉我为什么我没有OnAppearing方法,或者如果你能将你的方法改为OnStart,那对未来的观众来说可能会更好。