在异步方法 returns 值之前从异步方法导航到另一个 ContentPage

Navigate to another ContentPage from async method before the async method returns a value

我需要在此异步方法之前启动另一个 ContentPage returns 值:

public class GettingCountry : ContentPage
{
    public static List<string> CountriesList = new List<string>();

    MainPage mainPage = new MainPage();
    public async Task<List<RootObject>> FetchAsync(string url)
    {
        string jsonString;
        using (var httpClient = new System.Net.Http.HttpClient())
        {
            var stream = await httpClient.GetStreamAsync(url);
            StreamReader reader = new StreamReader(stream);
            jsonString = reader.ReadToEnd();
        }

        var listOfCountries = new List<RootObject>();

        var responseCountries = JArray.Parse(JObject.Parse(jsonString)["response"]["items"].ToString());

        foreach (var countryInResponse in responseCountries)
        {
            var rootObject = new RootObject((int)countryInResponse["id"], (string)countryInResponse["title"]);

            CountriesList.Add(rootObject.Title);
        }

        //I NEED TO NAVIGATE TO FillingPage() FROM HERE:
        await Navigation.PushAsync(new FillingPage());

        //await Navigation.PushModalAsync(new NavigationPage(new FillingPage()));

        return listOfCountries;
    }

需要启动的页面是:

[XamlCompilation(XamlCompilationOptions.Compile)]
public partial class FillingPage : ContentPage
{
    public FillingPage ()
    {
        GettingCountry gettingCountry = new GettingCountry();

        Label header = new Label
        {
            Text = "Заполните бланк",
            FontSize = Device.GetNamedSize(NamedSize.Large, typeof(Label)),
            HorizontalOptions = LayoutOptions.Center,
            VerticalOptions = LayoutOptions.CenterAndExpand,
            TextColor = Color.Blue
        };

        Entry nameEntry = new Entry()
        {
            Placeholder = "Имя",
        };

        Entry surnameEntry = new Entry()
        {
            Placeholder = "Фамилия"
        };

        Picker countryPicker = new Picker()
        {
            Title = "Страна",
            VerticalOptions = LayoutOptions.CenterAndExpand
        };

        foreach (string country in GettingCountry.CountriesList)
        {
            countryPicker.Items.Add(country);
        }

        SearchBar townSearchBar = new SearchBar()
        {
            Placeholder = "Город",
            SearchCommand = new Command(() =>
            {
            })
        };

        SearchBar universitySearchBar = new SearchBar()
        {
            Placeholder = "Университет",
            SearchCommand = new Command(() =>
            {
            })
        };
        Button myButton = new Button()
       {
           TextColor = Color.Green,
           Text = "Выполнить",
           FontSize = 22
       };

        // Accomodate iPhone status bar.
        this.Padding = new Thickness(10, Device.OnPlatform(20, 0, 0), 10, 5);

        // Build the page.
        this.Content = new StackLayout
        {
            Children =
            {
                header,
                nameEntry,
                surnameEntry,
                countryPicker,
                townSearchBar,
                universitySearchBar,
                myButton
            }
        };
    }
}

}

但是此代码 await Navigation.PushAsync(new FillingPage()); 只有在我按下按钮时才能正常工作。当我按下一个按钮时,所需的页面会很好地启动。但是方法中的相同代码不起作用。我已经debagged它。它转到 FillingPage() 但当我尝试从异步方法内部启动它时不会启动它。

这可能是操作未在主线程上执行的结果。尝试像这样包装您的代码:

Device.BeginInvokeOnMainThread(async () =>
{
    await Navigation.PushAsync(new FillingPage());
}

编辑: 私信后才知道问题中信息量不够,无法知道真正的问题。该应用程序在 Application.OnStart 中调用 FetchAsync 并且它根本不是视图层次结构的一部分,因此导航方法将不起作用。提供了以下内容:

protected override void OnStart ()
{
    getCountry();
}

private async void getCountry()
{
    var url = "...";
    GettingCountry gettingCountry = new GettingCountry();
    await gettingCountry.FetchAsync(url);
}

GettingCountry 是一个 ContentPage 被用作某种数据访问 class,它目前不是 UI 的一部分,因为 MainPage 已设置到别的东西。快速破解更像是:

private async void getCountry()
{
    var url = "...";
    GettingCountry gettingCountry = new GettingCountry();
    var data = await gettingCountry.FetchAsync(url);
    await MainPage.Navigation.PushAsync(new FillingPage(data));
 }

我建议进一步改进两个方面。

  1. 考虑重构 GettingCountry,因为它不需要是 ContentPage
  2. 调查替代呼叫,以便不使用 async void