2017-12-30 18 views
-2

これは私が思ったほど良く非同期のものを把握してはいけません。私が達成しようとしている何UIコマンド* previous *非同期タスクが有効な場合、非同期タスクは動作しません。

は次のとおりです。

  1. スイッチUI「データを取得しています...」する
  2. 非同期呼び出し
  3. に基づく非同期呼び出しとデータ
  4. 現在の最終結果を取得

私は私の見解で

private void Button_Click(object sender, RoutedEventArgs e) 
    { 
     GeneratorButton.IsEnabled = false; 
     ResultMsg.Visibility = Visibility.Visible; //default text of "Fetching data..." 
     string tickersString = Tickers.Text; 

     if (!string.IsNullOrEmpty(tickersString)) 
     { 
      tickersString = tickersString.ToUpper(); 
      string[] tickers = tickersString.Split(',', ' '); 

      var stockGeneratorTask = Task.Factory.StartNew<bool>(() => GetStockDataAndGenerateCSV(tickers).Result); 

      var allTasks = new Task[] { stockGeneratorTask }; 
      var tasksHandler = Task.Factory.ContinueWhenAll(allTasks, completedTasks => 
      { 
       return stockGeneratorTask.Result; 
      }); 

      if (tasksHandler.Result) 
      { 
       ResultMsg.Foreground = Brushes.Green; 
       ResultMsg.Text = "Your report was successfully generated."; 
      } 
      else 
      { 
       ResultMsg.Text = "There was an error while generating your report. Please try again later."; 
       ResultMsg.Foreground = Brushes.Red; 
      } 
     } 

     GeneratorButton.IsEnabled = true; 
    } 
0を私のWPFのボタンから次のコールバックを持っています

私の期待は、ユーザーがボタンを押すとすぐに、可視性プロパティの切り替えのために「データを取得しています...」というデフォルトのテキストが表示されることです。何が起こっているのは、私が理解していることは、プログラムが非同期タスクにまっすぐに進んでいることです。それが戻ってくると成功(またはエラー)メッセージが表示されますが、「データを取得...」をスキップしますstockGeneratorTaskの宣言からコードを削除します(非同期呼び出しは発生しません)。

非同期タスクがトリガーされる前にこのビジビリティスイッチが起きている場合は、実際に非同期呼び出しを行う前にこの変更が表示されませんか?なぜ私はそれが戻った後にそれを見ているのですか?

+2

私は何かが欠けている場合を除き、あなただけのプライベート '非同期のボイドButton_Click'にdefであなたの方法を変更したいと思います...、あなたの' tickers'宣言の間のすべてを取り除くとget 'if'ステートメントを呼び出し、' if'を 'if(GetStockDataAndGenerateCSV(tickers)await)... 'に変更します。あなたが今それをやっているところ(待たずにタスクの 'Result'プロパティにアクセスする)がブロックされています(非同期ではありません)。 –

+2

コードはすべて同期しています。 'あなたが何をしているのか正確に分かっていなければ' Task.Factory.StartNew'を使わないでください(http://blog.stephencleary.com/2013/08/startnew-is-dangerous.html)。 – CodingYoshi

答えて

0

async voidを許可するイベントハンドラは例外です。イベントハンドラをすべて非同期にし、デッドロックにつながる可能性がある.Resultなどのブロッキングコールを混在させないようにしてください。 GetStockDataAndGenerateCSVTask<bool>を返すと仮定すると、それは待たれるべきです。

private async void Button_Click(object sender, RoutedEventArgs e) { 
    GeneratorButton.IsEnabled = false; 
    ResultMsg.Visibility = Visibility.Visible; //default text of "Fetching data..." 
    var tickersString = Tickers.Text; 

    if (!string.IsNullOrEmpty(tickersString)) { 
     tickersString = tickersString.ToUpper(); 
     string[] tickers = tickersString.Split(',', ' '); 
     if (await GetStockDataAndGenerateCSV(tickers)) { 
      ResultMsg.Foreground = Brushes.Green; 
      ResultMsg.Text = "Your report was successfully generated."; 
     } else { 
      ResultMsg.Foreground = Brushes.Red; 
      ResultMsg.Text = "There was an error while generating your report. Please try again later."; 
     } 
    } 

    GeneratorButton.IsEnabled = true; 
} 

リファレンスAsync/Await - Best Practices in Asynchronous Programming