【问题标题】:Code is skipping back to calling function after await call代码在等待调用后跳回调用函数
【发布时间】:2017-01-27 02:57:56
【问题描述】:

我正在尝试使用 Xamarin 快速破解一个基本的移动应用程序以访问本地 API。我在 VS2015 中创建了一个默认的 Xamarin.Forms PCL 项目,并尝试添加代码以访问我在本地运行的 API。但是,当我到达 var response = await client.GetAsync(uri) 行时,代码执行并立即跳回到 RefreshDataAsync() 之后的行,从而绕过了半个函数,包括 try/ 的 catch 和 finally 块捕获声明。我已经在应用程序的每一行添加断点,并且它 100% 不会调用超出 await GetAsync 调用的任何代码。

几个小时后,我不得不承认我对这个应用程序中到底发生了什么感到茫然,因为我以前从未遇到过等待/异步的问题。

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!");
        }
    }
  }
}

【问题讨论】:

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


    【解决方案1】:

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

    所以刷新数据的正确方法是在 OnAppearing() 中使用 await 关键字调用 RefreshDataAsync() 并使用异步标记 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 来重组代码,但这不是您的问题的重点。

    【讨论】:

    • 嘿,谢谢。是的,代码现在只是被破解了。一旦它工作,我计划在另一个应用程序中正确实现它。我无法覆盖 OnAppearing 方法,因为我收到一条错误消息,指出它不存在。但是如果我按照你说的做,但是在 OnStart 中,它可以工作。当然,我得到了一个不同的错误,但你的回答似乎为我解决了这个问题。我已将您的答案标记为答案,但如果您能告诉我为什么我没有 OnAppearing 方法,或者您是否可以将方法更改为 OnStart,这可能对未来的观众更好。
    猜你喜欢
    • 1970-01-01
    • 2021-06-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-07-19
    • 1970-01-01
    • 2022-11-15
    • 1970-01-01
    相关资源
    最近更新 更多