2014-09-11 5 views
0

Microsoft 웹 API 2.2 클라이언트를 사용하여 API 끝점에서 데이터를 요청하고 있습니다. 데이터를 얻은 후에 x 개의 DoSomeWork를 실행합니다. DoSomeWork 함수를 실행하기 전에 데이터를 먼저로드해야합니다.다른 작업을 실행하기 전에 작업을 완료하는 방법

아래 코드를 기반으로 다음과 같은 결과가 예상됩니다.

은 "GetSomething 시작"

을 을 "작업 # 1 시작" "작업 # 2 시작" "GetSomething으로 완료"그러나 나는 다음 getthe 작업 # 시작 " 을"GetSomething 시작 " 1 " 는"GetSomething으로 완료 " "나는믿는다 "

static void Main() 
    { 
     try 
     { 
      Task getSomethingTask = Task.Factory.StartNew(()=>GetSomething()); 
      getSomethingTask.Wait(); 
      Task[] tasks = new Task[2] { 
       Task.Facotry.StartNew(()=>DoSomeWork(1)), 
       Task.Facotry.StartNew(()=>DoSomeWork(2)) 
      }; 
      Task.WaitAll(tasks); 
     } 
     catch(Exception ex) 
     { 
      throw ex; 
     } 
    } 
    static async Task GetSomething() 
    { 
     Console.WriteLine("Starting GetSomething"); 
     try 
     { 
      HttpClient client = new HttpClient(); 
      client.BaseAddress = new Uri(SOME_URL); 
      client.DefaultRequestHeaders.Accept.Clear(); 
      client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json")); 
      HttpResponseMessage response = await client.GetAsync("api/v1/somethings"); 
      somethingList = await response.Content.ReadAsAsync<SomeObject>(); 
     } 
     catch (Exception) 
     { 

      throw; 
     } 
     Console.WriteLine("Done with GetSomething"); 
    } 
    static async Task DoSomeWork(int workNumber) 
    { 
     Console.Writeline("Start work#" + workNumber); 
    } 

답변

1

때 (즉,가, 내가/O는 바인딩), 당신은 StartNew을 피하려고 비동기 프로그래밍을하고 , WaitWaitAll. 대신 거의 모든 로직에 asyncawait을 사용하십시오.

콘솔 앱이므로 메인 스레드가 종료되지 않도록 단일 Wait이 필요합니다. 이는 전체 응용 프로그램의 유일한 Wait해야한다 :

static void Main() 
{ 
    MainAsync().Wait(); 
} 

static async Task MainAsync() 
{ 
    await GetSomethingAsync(); 
    await Task.WhenAll(DoSomeWorkAsync(1), DoSomeWorkAsync(2)); 
} 

static async Task GetSomethingAsync() 
{ 
    Console.WriteLine("Starting GetSomething"); 
    HttpClient client = new HttpClient(); 
    ... 
    HttpResponseMessage response = await client.GetAsync("api/v1/somethings"); 
    somethingList = await response.Content.ReadAsAsync<SomeObject>(); 
    Console.WriteLine("Done with GetSomething"); 
} 

static async Task DoSomeWorkAsync(int workNumber) 
{ 
    Console.Writeline("Start work#" + workNumber); 
} 

당신은 내 async intro 도움을 찾을 수 있습니다.

0

을 작업 # 2를 시작합니다 await을 보내지 않으므로이 즉시 완료됩니다. GetSomething().

이 시도 : 단순히

Task getSomethingTask = Task.Factory.StartNew(async() => await GetSomething()); 

또는 :

GetSomething().Wait(); 

난 당신이 정말 주에 결과를 기다리고 즉시 새 스레드를 만들고으로 아무것도 얻고 있다고 생각하지 않지만 실.

0

스레드에서 await으로 호출하면 제어가 상위 스레드로 되돌아갑니다. 즉시 당신이 당신의 GetSomething 스레드 수익률은 다시 당신이 당신의 DoSomeWork 작업을 실행 볼 이유입니다 Main() 스레드, 제어, 그렇게으로

HttpResponseMessage response = await client.GetAsync("api/v1/somethings"); 

:이 경우

이 당신의 기분을 상하게하는 라인입니다.

await 호를 제거하고 GetSomething 호를 호출하고 대신 동기 호 수로 바꾼다면 원하는 동작을 얻게됩니다. 더 많은 정보를 들어

, 여기에 마이크로 소프트의 비동기 프로그래밍 설명서를 참조하십시오 (특히 단계 # 6은 약 await 회담 곳) : http://msdn.microsoft.com/async

관련 문제