2016-06-12 9 views
0

私は単純な汎用アプリケーションを作成して、ビットコインの価格をWebから取得しようとしています。私はhereからURLからjsonを取得して文字列に入れる非同期メソッドを持っています。C#ユニバーサルアプリケーションで非同期メソッドが検出されない

 public App() 
     { 
      this.InitializeComponent(); 
      this.Suspending += OnSuspending; 

      CoinPriceBackend CP = new CoinPriceBackend(); 

      string response = await GetFromAPI(); 
     } 

そして、これはメソッドです::ここで私は法と呼ばれるところである

 async Task<string> GetFromAPI() 
     { 
      try 
      { 
       //Create HttpClient 
       HttpClient httpClient = new HttpClient(); 

       //Define Http Headers 
       httpClient.DefaultRequestHeaders.Accept.TryParseAdd("application/json"); 

       //Call 
       string ResponseString = await httpClient.GetStringAsync(
        new Uri("https://api.bitcoinaverage.com/ticker/GBP/")); 
       //Replace current URL with your URL 

       return ResponseString; 
      } 

      catch (Exception ex) 
      { 
       return "ERROR: " + ex; 
      } 
     } 

私はエラー

'The 'await' operator can only be used within an async method. 
Consider marking this method with the 'async' modifier and changing its return type to 'Task'.' 

を得る。しかしこの方法非同期です...どのように私はこれを修正できますか?

ありがとうございます!

+2

を**非同期メソッド内でのみ**使用できます。 "* - あなたの' App'コンストラクタは使用できません。 – IInspectable

答えて

0

関数内でawaitを使用する場合は、関数をasyncと定義する必要があります。

しかし、App()コンストラクタの場合、それを行うことはできません。 stringを返す関数を呼び出すことができる別の関数を定義することができます。このよう

public App() 
{ 
    CallApi(); 
} 

private async void CallApi() 
{ 
    response = await GetFromAPI(); 
} 
+0

タスク**は** asyncです。これがポイントです - これはメソッドのオープナーです:asyncタスク GetFromAPI() – MattyAB

+0

あなたはApp()コンストラクタに 'async'を使用していません。しかし、これの中であなたが許可されていない待ちを使用しようとする –

+0

C#のコンストラクタは非同期としてマークすることはできません –

0

C#がコンストラクタは非同期としてマークすることはできません。

次の3つの主要なオプションがあります。

1)は、非同期イベントハンドラでこのメソッドを呼び出すためにリファクタリング。

2)Task.Runを使用して新しいスレッドを生成し、そこで非同期コードを実行します。これは、結果をUIスレッドにマーシャリングし、一部のUI要素に値を割り当てる問題につながる可能性があります。

3)同期呼び出しをブロックします。これはおそらく最も簡単なオプションです。

次の変更を行う必要があります。

string response = GetFromAPI().Result; 

タスクは、したがって、あなたは別の変更を必要とし、すでに「.Result」への呼び出しによってロックされているメインスレッドでreaumeにしようとすると、これはおそらく、デッドロックが発生することに注意してください。また、意味がありません

Task<string> GetFromAPI() 
{ 
    .... 

    return httpClient.GetStringAsync(new Uri("https://api.bitcoinaverage.com/ticker/GBP/")).ConfigureAwait(false); 

    ... 
} 
1

しかし、この方法非同期

は、エラーメッセージを詳しく見てみましょうです。それはGetFromAPIについて話していない - それはAppについて話している。

しかし、他の人が指摘しているように、コンストラクタasyncと表示されません。

私は

ユニバーサルWindowsアプリケーションの簡単なユニバーサルアプリを書くことをしようとしている - 他のすべての近代的なプラットフォームのような - ことはできませんブロックI/Oベースの操作のためのUIスレッド。ユーザーエクスペリエンスはあまりにも悪く、ほとんどのアプリストアではこれを行うアプリを自動拒否するテストが行​​われています。

別の言い方をすると、Appが(おそらく)アプリケーションの起動時に呼び出されます。ユーザーがアプリを起動すると、すぐにが起動し、と表示されます()。ダウンロードが完了するのを待つことは、単にオプションではありません。

ので、本当に修正これまで、あなただけの開始ダウンロード(それが完了するのを待っていない)に必要と「ロード」状態にアプリケーションを初期化する - スピナーや「ロードを示します... "メッセージか何でも。ダウンロードが完了したら、を更新して、必要なものを表示します。

(あなたがMVVMをやっている場合)、私はasync MVVMasync constructors上のブログの記事と記事のシリーズを持っていますが、本当に基本的なアプローチは、このようなものになります: "*『待つ』演算子を

public Task Initialization { get; } 
public string Value { get; private set { /* code to raise PropertyChanged */ } } 

public App() 
{ 
    this.InitializeComponent(); 
    this.Suspending += OnSuspending; 

    CoinPriceBackend CP = new CoinPriceBackend(); 

    Value = "Loading..."; // Initialize to loading state. 
    Initialization = InitializeAsync(); 
} 

private async Task InitializeAsync() 
{ 
    try 
    { 
    string response = await GetFromAPI(); 
    ... 
    Value = response; // Update data-bound value. 
    } 
    catch (Exception ex) 
    { 
    ... // Display to user or something... 
    } 
} 
関連する問題