2017-05-16 7 views
1

ToArray()가 실행될 때 작업이 시작되는 이유를 이해하려고 시도합니다. 그리고 DoSomething 메서드에 넣은 중단 점이 절대로 손상되지 않습니다.LINQ/async/await

private async void MyMethod() 
{ 
     await NewMethod(); 
     string[] array = { "http://google.com", "http://microsoft.com"}; 
     IEnumerable<Task<string>> query = from url in array select DoSomething(url); 
     Task<string>[] tasks = query.ToArray(); 
     string[] contents = await Task.WhenAll(tasks); 
} 

private async Task<string> DoSomething(string url) 
{ 
     HttpClient hc = new HttpClient(); 
     string content = await hc.GetStringAsync(url); 
     return content; 
} 

실제로 ToArray()가 작업을 시작하면 DoSomething 메서드의 중단 점에서 실행이 중지되어야합니다.

당신에게 콘솔 응용 프로그램에 Async Main을 사용하여 코드의 다음 버전을

+5

이는 linq의 동작입니다. 실제 쿼리는 결과 세트가있는 것을 원하지 않는 한 실행되지 않습니다. linq에서 지연 및 즉각적인 쿼리 실행을 살펴보십시오. –

+0

'DoSomething' 코드를 입력하고 거기에 중단 점을 어디에 두 었는지 보여줍니다. 당신이 여전히 실행해야 할 몇 가지 작업이 반환되고 있습니다. –

+0

그리고'Task's ('await','WaitAll()','WhenAny()'등을 어떻게 실행하는지 보여주세요. – dymanoid

답변

0

체크 아웃 감사 :

이제 MyMethod()은 두 가지 방법으로 다음 호출 할 수 있습니다
private async Task MyMethod() 
{ 
    await NewMethod(); // Contains Place holder wait code 
    string[] array = { "http://google.com", "http://microsoft.com" }; 
    IEnumerable<Task<string>> queryTasks = from url in array select DoSomething(url); 
    string[] contents = await Task.WhenAll(queryTasks); 
    contents.Dump(); 
} 

private async Task<string> DoSomething(string url) 
{ 
    HttpClient hc = new HttpClient(); 
    string content = await hc.GetStringAsync(url); 
    return content; 
} 

private async Task NewMethod() 
{ 
    // Placeholder Task.Delay 
    await Task.Delay(1000); 
} 

: 먼저

:

async Task Main() 
    { 
     await MyMethod(); 
    } 

둘째 :

async void Main() 
    { 
     await MyMethod(); 
    } 

는 위의 두 경우에 디버깅 이상적으로 할 수 있어야한다, 그러나 void Main()의 경우, 메인 스레드가 DoSomething에서 브레이크 포인트에서 코드를 나누기 전에/종료를 반환하지만, 간단한 예로는 NewMethod()에 이 포함되어 있고이 코드를 await Task.Delay(1);으로 변경하면 모든 경우에 오류가 발생하는 것을 볼 수 있습니다. 그렇지 않으면 DoSomething 메서드의 중단 점이 코드 흐름을 중단하기 전에 void Main이 종료됩니다. 대신 Task Main()은 모든 경우에 코드 분할을 보장하므로 계속하기 전에 태스크 완료를 기다려야합니다.

다른 중요한 세부 사항 : 당신은 Task.WhenAll이 같은 작업을 수행하는 실행을 시작 query.ToArray() 필요하지 않습니다

  1. 자사의 IEnumerable<Task<string>>을 제공하지만 ToArray() 호출 이전에 사용 구체화되었다 여전히 지연된 실행