2017-12-30 21 views
-2

비동기 작업에 대해서는 생각보다 좋게 파악하면 안됩니다. 지금 내 머리를 두 시간 동안 긁어 버렸기 때문에 생각했습니다.UI 명령 * 비동기 작업을 사용하는 경우 비동기 작업을 수행 할 수 없습니다.

내가 달성하기 위해 노력하고있어 것은 님의

  1. 스위치 UI '를 가져 오는 데이터를 ... "
  2. 비동기 호출
  3. 를 기반으로하는 비동기 호출
  4. 현재 최종 결과 데이터를 가져 오기

나는 내보기에 내 WPF 버튼에서 다음 콜백을 가지고

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; 
    } 

사용자가 버튼을 누르 자마자 가시성 속성 전환으로 인해 "데이터 가져 오기 중 ..."이라는 기본 텍스트가 표시됩니다. 내가 이해하는 바로는, 프로그램이 비동기 작업으로 곧바로 진행된다는 것이고, 그것이 돌아 왔을 때 성공 (또는 오류) 메시지를 보여 주지만, "데이터를 가져 오는 중 ..."을 건너 뜁니다. 내가 코멘트하지 않는 한 stockenerGeneratorTask (비동기 호출 발생 없음) 선언에서 코드를 내 보낸다.

이제 비동기 작업이 시작되기 전에이 표시 여부 전환이 발생하면 비동기 호출을 실제로 만들기 전에이 변경 사항이 표시되지 않아야합니까? 왜 돌아온 후에 만 ​​볼 수 있습니까?

+2

뭔가 ... 당신이 개인 비동기 무효 Button_Click''에 DEF 귀하의 방법을 변경하려면 단지 것, 당신의'tickers' 선언 사이에 모든 것을 제거를 누락하지 않는 한 'if' 문을 수정하고'if'를'if (GetStockDataAndGenerateCSV (tickers) await ...) '로 변경하십시오. 현재 (작업을 기다리지 않고 '결과'속성에 액세스하는) 지금 차단하는 중입니다 (비동기가 아닌). –

+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

관련 문제