2016-04-22 12 views
1

HttpClient経由でRESTful WCFサービスからデータをロードする非同期呼び出しを作成しようとしています。このコードは、Xamarin UIから使用されるPortable Class Library(PCL)にあります。非同期呼び出しは決して起動されないようです。私はこの分野の問題についてのブログを読んだので、私はそれらに対処したと信じています。非同期呼び出しが一度も実行されない

public MyRepository() 
    { 
     Task.Run(async() => { await LoadDataAsync(url); }); 
    } 
    public async Task LoadDataAsync(string uri) 
    { 
     if (allRecords != null) **// Breakpoint here never hit.** 
     { 
      string responseJsonString = null; 

      using (var httpClient = new HttpClient()) 
      { 
       try 
       { 
        Task<HttpResponseMessage> getResponse = httpClient.GetAsync(uri); 
        HttpResponseMessage response = await getResponse; 
        responseJsonString = await response.Content.ReadAsStringAsync(); 
        myList = JsonConvert.DeserializeObject<List<MyListItem>>(responseJsonString); 
       } 
       catch (Exception ex) 
       { 

       } 
      } 
     } 
    } 

感謝すべてのヘルプ:

私は以下のようにクライアント側のデータリポジトリクラスから電話をかけます。前もって感謝します。

+0

本当に空の 'catch(Exception ex)'はしないでください。バグを診断するのが難しいエラーを隠すだけです。 –

+0

これはデスクトップ.N​​ETで再現できますか? –

答えて

-2

なぜ発火していないのか:おそらく、Task.Runで開始しようとするスレッドが実際に起動する前に、アプリケーションが終了している可能性があります。 、上記の理論をテスト呼び出す直後のThread.sleepを置くために

(これは解決策が、テストではありません):非同期メソッドを利用するために、とにかく

public MyRepository() 
{ 
    Task.Run(async() => { await LoadDataAsync(url); }); 
    System.Threading.Thread.Sleep(10000); //will sleep for 10 seconds 
} 

ますあなたは実際にそれを待つ必要があるまで、あなたが実際に待つ必要があるまで、他のことを行うことを可能にする "getresponse"オブジェクト上で実行された待った後に、スレッドは、関数で直接待機するTask.Runを削除する必要がありますそれを待ってください。私があなただったら、私は...コンストラクタ内部の非同期メソッドを呼び出す

を回避し、この

ような何かをするだろう

+0

downvoteの理由は何ですか? –

2

(あなたのクラスのインスタンスを返す静的メソッドを作成します)

const string uri = "https://www.webservice.com/api/getdata"; 
    private List<MyListItem> myList; 

    public static async Task<MyRepository> GetMyRepository() 
    { 
     MyRepository myRepository = new MyRepository(); 
     await myRepository.LoadDataAsync(uri); 

     return myRepository; 
    } 

    public MyRepository() 
    { 
    } 

    public async Task LoadDataAsync(string uri) 
    { 
     if (allRecords != null) **// Breakpoint here never hit.** 
     { 
      string responseJsonString = null; 

      using (var httpClient = new HttpClient()) 
      { 
       try 
       { 
        Task<HttpResponseMessage> getResponse = httpClient.GetAsync(uri); 
        HttpResponseMessage response = await getResponse; 
        responseJsonString = await response.Content.ReadAsStringAsync(); 
        myList = JsonConvert.DeserializeObject<List<MyListItem>>(responseJsonString); 
       } 
       catch (Exception ex) 
       { 

       } 
      } 
     } 
    } 

なぜあなたはその問題に遭遇しているのか説明できませんが、おそらくこれが役立つかもしれません。

+0

これは良い解決策ですが、私がやる変更の1つは、静的なファクトリメソッドを使用してコンストラクタをプライベートにして、ファクトリメソッドだけが新しいインスタンスをインスタンス化できるようにしたことです。 –

+0

ええ、スレッドセーフなシングルトンクラスに変換する必要があります。 –

0

問題は、コンストラクタ内から "fire-and-forget"非同期呼び出しを呼び出すことです。これは回避され、あなたのコードが呼び出されていないように見えるという理由であるべきである - それはおそらくあるとき...私は次の変更を行うことをお勧め:除き、実際に変更はありませんか

public async Task LoadDataAsync(string uri) 
{ 
    if (allRecords != null) **// Breakpoint here never hit.** 
    { 
     string responseJsonString = null; 

     using (var httpClient = new HttpClient()) 
     { 
      try 
      { 
       Task<HttpResponseMessage> getResponse = httpClient.GetAsync(uri); 
       HttpResponseMessage response = await getResponse; 
       responseJsonString = await response.Content.ReadAsStringAsync(); 
       myList = JsonConvert.DeserializeObject<List<MyListItem>>(responseJsonString); 
      } 
      catch (Exception ex) 
      { 

      } 
     } 
    } 
} 

お知らせすべてのコンストラクタを削除します。このオブジェクトがインスタンス化されるとき、単にLoadDataAsync関数の呼び出しを待ちます。

public async Task SomeConsumerOfYourObject() 
{ 
    var wcfObj = new YourWcfObject(); 
    await wcfObj.LoadDataAsync(this.Uri); 

    // Then you're good... 
} 
関連する問題