C# 等待调用后,代码跳回调用函数

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

我正在尝试用Xamarin快速破解一个基本的移动应用程序,以实现本地API。我在VS2015中创建了一个默认的Xamarin.Forms PCL项目,并尝试添加代码以命中我在本地运行的API。但是,当我到达var response=await client.GetAsync(uri)行时,代码执行并在RefreshDataAsync()之后立即跳回该行,从而绕过了半个函数,包括try/catch语句的catch和finally块。我甚至在应用程序中的每一行都添加了断点,它100%不会调用wait-GetAsync调用之外的任何代码

几个小时后,我不得不承认我对这个应用程序到底发生了什么感到困惑,因为我以前从未遇到过wait/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!");
        }
    }
  }
}
使用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,那对未来的观众来说可能会更好。