2017-01-25 1 views
0

이 예제에서는 스레드가 어떻게 흐르고 있는지 궁금합니다. 비동기 이벤트 핸들러가 있으며 다른 비동기 메소드를 호출합니다.이 메소드에는 두 가지 대기가 있습니다. 이 같은 흐름을 이해할 수있다 :멀티 레이어 비동기 제어 흐름

  • 1) UI 스레드를 Button1_Click를 호출이 순차적으로 LoadStringAsync 메소드를 호출을
  • 2) LoadStringAsync가 GetFirstNameAsync 처음
  • 3) GetFirstNameAsync가 기다리고이 완료되지 않은 작업, LoadStringAsync 반환 호출 작업
  • 4) LoadStringAsync 차례를 Button1_Click 는 UI 스레드를 Button1_Click 잎 LoadStringAsync
  • 5)에 의해 반환되는 작업을 기다립니다, 완료되지 않은 작업을 반환합니다. 이것이 UI 스레드가 을 차단하지 않는 이유입니다.
  • 6) GetFirstNameAsync가 결국 완료되면 LoadStringAsync는 으로 계속 진행될 수 있습니다. 즉 UI 스레드가 다시 들어올 것이며 다음 번에 또 다른 행인 이 실행될 것입니다.
  • 8) GetLastNameAsync가 완료되지 않은 작업이 LoadStringAsync 이
  • 9 GetLastNameAsync
  • 에 의해 반환 된 작업)를 Button1_Click는 UI 스레드가 다시를 Button1_Click 잎 LoadStringAsync
  • 10)에 의해 반환되는 작업을 기다리고 기다리고 반환하고 다른 작업을 수행.
  • 11) 동일한 단계가 반복됩니다.

제 가정은 맞습니까? 또는 여기에 교착 상태가 있습니다.

private async void button1_Click(object sender, RoutedEventArgs e) 
{ 
string s = await LoadStringAsync(); 
textBox1.Text = s; 
} 

static async Task<string> LoadStringAsync() 
{ 
string firstName = await GetFirstNameAsync(); 
string lastName = await GetLastNameAsync(); 
return firstName + ” ” + lastName; 
} 
+0

설명하신 흐름이 적절하다고 생각됩니다. LoadStringAsync, GetFirstNameAsync 등과 같은 세부 사항을 제공하지 않았기 때문에 여기서 교착 상태가 발생하지 않는지 확실히 말할 수는 없습니다. 거기에 차단 호출이 없으면 정상이어야합니다. –

+0

자세한 내용은 https://msdn.microsoft.com/en-us/magazine/jj991977.aspx를 참조하십시오. –

답변

1

귀하의 흐름은 거의 정확합니다. 한 가지 수정 : 메소드가 두 번 반환되는 것은 불가능합니다 (4 단계와 9 단계). LoadStringAsync은 이미 완료되지 않은 작업을 반환 했으므로 두 번째 await의 UI 스레드로 직접 반환됩니다.

제공 한 코드에는 교착 상태가 없습니다.

+0

또한 'LoadStringAsync()'내부에서'.ConfigureAwait (false)'를 사용한다면,'await LoadStringAsync()'가 완료 될 때까지 UI 쓰레드를 다시 고칠 필요가 없다는 것을 지적 할 가치가 있습니다 ; 그 대신 ThreadPool 스레드가 사용됩니다. – sellotape

+0

@Stephen Cleary, 귀하의 의견에 감사드립니다. 지난 며칠 동안, 나는 당신의 블로그를 읽었습니다. 교착 상태 블로그를 읽은 후에도 교착 상태 문제가 없다고 생각합니다. 그러나 귀하의 교착 블로그에는 두 가지 예가 기다리고 있지 않습니다. 그런 다음이 블로그 (https://blogs.msdn.microsoft.com/pfxteam/2011/01/13/await-and-u-and-deadlocks-oh-my/)를 읽었습니다. 내 예제 코드는 실제로 거기에서 가져온 것입니다. Stephen Toub은 교착 상태라고 말했습니다. (그의 말을 잘못 이해하지 않는 한) .... –

+0

@sellotape는 다음과 같이 이해할 수 있습니다. .ConfigureAwait (false)가 사용되면 스레드 A threadpool에서 LoadStringAsync()를 기다리고 스레드 A가 button_Click 메서드에서 최종 문자열을 변수 s에 반환합니다. 그러면 어떤 스레드가 textBox1을 업데이트합니까? UI 스레드가 아닌 경우 예외가 발생합니다. - –