2017-01-27 24 views
1

Xamarinで基本的なモバイルアプリケーションをすばやくハックしてローカルAPIにヒットしようとしています。 VS2015でデフォルトのXamarin.Forms PCLプロジェクトを作成し、ローカルで実行しているAPIにヒットするコードを追加しようとしました。しかし、私は行のvar応答=待っているclient.GetAsync(uri)を実行すると、コードが実行され、すぐに戻って、RefreshDataAsync()の後の行にジャンプするので、catch/finallyブロックのtry/catchステートメント。私は、アプリケーションのすべての行にブレークポイントを追加するために行っており、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

関数RefreshDataAsync()は、定義したとおりに非同期です。しかし、コンストラクターで呼び出すと、コンストラクター呼び出しが非同期ではないため、呼び出すことができません。したがって、あなたが示した方法を呼び出し、そのような方法で呼び出しが待たれていないので、呼び出しの完了前にプログラムの実行フローが継続します。

データをリフレッシュする正しい方法は、OnAppearing()のawaitキーワードでRefreshDataAsync()を呼び出し、OnAppearingにasyncをマークすることです。 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を動かしてコードを再構成したいかもしれませんが、それはあなたの質問のポイントではありませんでした。

+0

ありがとうございます。ええ、コードはちょうど今のところ一緒にハッキングされています。私はそれがうまくいけば別のアプリで正しく実装するつもりです。 OnAppearingメソッドが存在しないというエラーが表示されるため、OnAppearingメソッドをオーバーライドできませんでした。しかし、私があなたが言ったことをやっても、OnStartでは、それは機能します。私は別のエラーが出ることは許されますが、あなたの答えは私の問題を解決したようです。 私は答えとしてあなたのマークを付けましたが、なぜ私がOnAppearingメソッドを持っていないのか、またはあなたのメソッドをOnStartに変更して将来の視聴者にとってはより良いかもしれないかを教えてください。 – xCasper

関連する問題