2017-03-20 1 views
0

が値を返す:移動非同期メソッドが返す前に、私は、この非同期メソッドの前に別のContentPageを開始する必要がある値

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());このコード。ボタンを押すと、必要なページがうまく始まります。しかし、メソッド内の同じコードは機能しません。私はそれを議論した。それはFillingPage()に行きますが、非同期メソッドの中から起動しようとすると起動しません。

+0

あなたの質問に完全に無関係なコメントのためのカップルです。 'httpClient.GetStringAsync()'を使って文字列を直接取得することができます。そして、 'HttpClient'を処分しない方がより効果的です。バックグラウンドでは、すべての要求間で共有されるインスタンスであり、それを廃棄するとオーバーヘッドが増えます。詳細はこちらを参照してください:https://aspnetmonsters.com/2016/08/2016-08-27-httpclientwrong/ –

答えて

3

これは、操作がメインスレッドで実行されていない可能性があります。このようなあなたのコードをラップしてみてください。

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

編集:をプライベートメッセージの後、私は本当の問題を知っている問題の十分な情報がなかったことを知りました。アプリケーションはをApplication.OnStartに呼び出しています。これはビューの一部ではないので、ナビゲーションメソッドは機能しません。

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

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

GettingCountryは、データアクセスクラスのいくつかの種類のように使用されてContentPageであり、それはMainPageが何か他のものに設定されているとして、現在、UIの一部ではありません。以下が提供されていました。クイックハックは、もっと似たようなものになります。

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

私は、改良を目指す2つのさらなる領域を提案します。

  1. リファクタリングをGettingCountryとすると、ContentPageである必要はありません。
  2. async voidが使用されないように別の呼び出しを調べます。
+2

なぜdownvote?答えを改善するために私は何ができますか? – therealjohn

+0

Device.BeginInvokeOnMainThreadは私が必要としていた答えでした。私は、非同期スレッドでMainPageを変更しようとしていました。 UI /メインスレッドでそれをやることは、私がやっていたはずのことでした。私がすぐに忘れることのないレッスン。 –

関連する問題