代码在等待调用后跳回到调用函数

时间:2017-01-27 02:57:56

标签: c# asynchronous xamarin async-await xamarin.forms

我正在努力与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!");
        }
    }
  }
}

1 个答案:

答案 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来重构代码,但这不是您的问题。