2016-07-16 13 views
0

私はXamarin Formsアプリケーションを開発していますが、私の質問はXamarin固有のものではないと思います。 ユーザーがピンコードを入力した後(もちろん、ピンが正しい場合のみ)、私は彼にタブ付きのページを表示します。これらのページにはいくつかのコントロールがありますが、もっと重要なことは、それぞれが非同期呼び出しを使用してWebからデータを取得する必要があることです。さて、私のアプリケーションはいくつかのタブを持っているので、それぞれのデータをすべて並列に(非連続的に)取り出したいと思っています。私がこれまで実施してきたもの、これは次のとおりです。アプリケーションデータをバックグラウンドで準備する方法は?

public MainTabbedPage(bool requirePin) 
    { 
     if (requirePin) 
     { 
      Navigation.PushModalAsync(new PinEntryPage(this)); 
     } 
     InitializeComponent(); 

    } 

    public void InitializeChildren() 
    { 
     try 
     { 
      var page1 = new Page1(); 
      page1.RefreshData(); 

      var page2 = new Page2(); 
      page2.RefreshButtons(); 
      page2.RefreshData(); 

      var page3 = new Page3(); 
      page3.RefreshData(); 

      Children.Add(page1); 
      Children.Add(page2); 
      Children.Add(page3); 
     } 
     catch (Exception ex) 
     { 
      // some error handling... 
     } 
    } 

このようなすべてのRefreshData()RefreshButtons()見ながら:それが正しいかどう今

public void RefreshData() 
    { 
     Task.Run(
      () => 
      { 
       var data = ApiSingleton.Instance.GetData().Result; 
       // some data manipulations 
       Device.BeginInvokeOnMainThread(() => /* some UI manipulation*/); 
       } 
      }); 
    } 

、これは右やっているように見える一方で、私は疑問に思いますそれをする方法、そうでない場合は、何ですか?

+1

'GetData()'はタスクのようです。したがって、 'RefreshData'を非同期にした後、彼の結果を待つことができます。 'Task.Run()'の必要はありませんimo – lokusking

+1

'GetData()'は非同期メソッドのように見えます(なぜなら 'Result'に触れるからです)。 –

+0

本当にありがとう、非同期です。私は 'Device.BeginInvokeOnMainThread'を必要としないでしょうか? – nicks

答えて

1

このようにそれを実行してください:あなたが一度にすべてのページのデータrefereshを開始する場合があります物事をスピードアップするための代替として

public async Task RefreshData() 
{ 
    var data = await ApiSingleton.Instance.GetData(); 
    // some data manipulations 
    // you are on the UI thread here 
    // so there is no nead for BeginInvokeOnMainThread  
} 

public MainTabbedPage(bool requirePin) 
{ 
    if (requirePin) 
    { 
     Navigation.PushModalAsync(new PinEntryPage(this)); 
    } 
    InitializeComponent(); 
} 

public async void InitializeChildren() 
{ 
    try 
    { 
     var page1 = new Page1(); 
     await page1.RefreshData(); 

     var page2 = new Page2(); 
     await page2.RefreshButtons(); 
     await page2.RefreshData(); 

     var page3 = new Page3(); 
     await page3.RefreshData(); 

     Children.Add(page1); 
     Children.Add(page2); 
     Children.Add(page3); 
    } 
    catch (Exception ex) 
    { 
     // some error handling... 
    } 
} 

とメソッドのための方法を更新。それはあなたが望むものであるならば、このようなものに変更しInitializeChildren:

public async void InitializeChildren() 
{ 
    try 
    { 
     var page1 = new Page1(); 
     var refreshPage1Task = page1.RefreshData(); 

     var page2 = new Page2(); 
     var refreshButtonsPage2Task = page2.RefreshButtons(); 
     var refreshPage2Task = page2.RefreshData(); 

     var page3 = new Page3(); 
     var refreshPage3Task = page3.RefreshData(); 

     await Task.WhenAll(new Task[] { 
      refreshPage1Task, refreshPage2Task, 
      refreshPage3Task, refreshButtonsPage2Task }); 

     Children.Add(page1); 
     Children.Add(page2); 
     Children.Add(page3); 
    } 
    catch (Exception ex) 
    { 
     // some error handling... 
    } 
} 

これは、一度にすべてのページのリフレッシュを開始しますので、ネットワーク操作が同時に実行することができます。各呼び出し後のUIスレッドへの戻りは引き続き発生します。 Task.WhenAllは、すべてのリフレッシュ操作が完了した後にのみ子コレクションにページが追加されるようにします。

+0

子ページをページに追加する前に子ページが初期化されるのを待つことで処理が速くなりますか? – nicks

+0

また、ユーザーが正しいピンを提供する前にデータを取り出すことを開始することは、私にはうれしくないと思います...それは大丈夫だと思いますか?それは安全ですか? – nicks

+1

GetDataメソッドが何らかの種類のデータアクセスを行っているとします。これは、データがディスクまたはネットワークからロードされると、他のタスクがすでに開始できることを意味します。ネットワーク要求が完了するまでに1秒かかり、元のコードが完了するまでに3秒かかりますが、すべての要求が同時に実行されるため、同時バージョンでは1秒以上の時間がかかります。 –

関連する問題