async + await == 동기화?


24

이 우연히 포스트 비동기 웹 요청을에 대해 이야기하는.

현실 세계에서 비동기 요청을하고 바로 다음 줄에서 대기하는 것이라면 간단합니다. 처음에 동기화 호출을하는 것과 동일하지 않습니까?


5
정확히. 코드는 결과를 얻을 때까지 아무 일도 일어나지 않는다는 의미에서 동기식입니다. 그러나 아래에서 비동기 메소드가 반환 될 때까지 실행중인 스레드를 포기 한 다음 다른 스레드를 할당하여 계속 실행할 수 있습니다.
R0MANARMY

2
그것은하지만 그런 다음 같은 시간에 다른 비동기 작업을 수행 할 수 있습니다 비동기로 이것이 가능하지 않은 동기로, 2를 기다리고
래칫 괴물

다음 은 C #의 비동기에 대한 일부를 설명 하는 기사 ( tomasp.net/blog/async-compilation-internals.aspx )입니다 .C # 및 F #의 비동기 프로그래밍을 다루는 시리즈의 일부입니다.
paul

@ratchetfreak : 예, 여러 번 전화를 거는 경우에는 말할 것도 없습니다.
Mr.

@ R0MANARMY : 앱이 다른 일을하고 있다면 yes와 async + await가 가능합니다. Akim이 가장 잘 말합니다! 그러나 코드가 button_click 핸들러 또는 해당 문제에 대한 이벤트 핸들러에없는 것으로 가정하십시오. 누군가가 맹목적으로 코드 (비동기 + 대기 라인)를 어떤 방법 으로든 복사하면 코드가 비동기이지만 실제로는 아닐 수 있다는 잘못된 인상을 줄 수 있습니다.
Mr.

답변:


32

아니, async + await != sync때문에의 계속

MSDN에서 'Async and Await를 사용한 비동기 프로그래밍 (C # 및 Visual Basic)'

비동기 메서드는 비 차단 작업입니다. 비동기 메서드의 대기 식은 대기중인 작업이 실행되는 동안 현재 스레드를 차단하지 않습니다. 대신, 표현식 은 나머지 메소드를 연속으로 등록하고 async 메소드의 호출자에게 제어를 리턴합니다 .

예를 들어 비동기 실행은 UI 스레드를 차단하지 않으며 Some TextBox.Text다운로드가 완료된 후에 업데이트됩니다.

private async void OnButtonClick()
{
   SomeTextBox.Text = await new WebClient().DownloadStringTaskAsync("http://stackoverflow.com/");
}

아주 잘 말했다!
Mr.

더 자세히 설명해 주시겠습니까? 이것이 없으면 ... 이것이 ... 당신은 UI와 상호 작용할 수 없을 것입니다 ... 이것은 메인 스레드에서와 같이. 이는 상호 작용이 웹 서버 스레드와 분리 된 웹에 적용되는 응용 프로그램 유형 프로그램에만 적용 할 수 있음을 의미합니다. 따라서 너트 셸에서는 주 스레드가 실행중인 스레드 일 때 동기화되지 않는 것이 중요합니다. 이로 인해 예기치 않은 동작이 발생하지 않습니까 (예 : App (1 메인 스레드)에서 두 개의 버튼 클릭). 그러나 첫 번째 완료없이 1을 클릭 할 수 있어야합니까?
Seabizkit

무엇에 대해 Console.WriteLine(await GetStringOverNetwork());? 비동기 호출의 출력이 필요한 경우 어떻게합니까? 스레드가 잠재적으로 실행을 계속할 수 있어도 프로그램이 처음 액세스 할 때 차단됩니까?
앤드류

6

아니요, 동일하지 않습니다.

귀하의 async코드 블록은 기다리고 있습니다 await,하지만 응용 프로그램의 나머지 부분은 대기하지 않습니다 계속 반환에 전화 여전히 정상처럼 계속할 수 있습니다.

반대로, 동기 호출은 전체 애플리케이션 또는 스레드가 코드 실행이 완료 될 때까지 기다렸다가 다른 작업을 계속하도록합니다.


동기화 호출을 async + await로 구현할 수 없습니까?
ratchet freak

@ratchetfreak 대기 / 비동기 설정에 약간의 오버 헤드가 있다고 생각하므로 전체 응용 프로그램을 코딩하고 싶지는 않습니다. 잠재적으로 장기 실행 코드 블록을 실행하는 데만 사용하므로 응용 프로그램을 잠그지 않습니다. :)
Rachel

5

async / await와 관련하여 명확하게 설명하겠습니다.

대기 상태가 발생하면 기본 상태 시스템에서 제어를 즉시 리턴 할 수 있습니다. 그런 다음 대기중인 통화가 완료되면 기본 상태 시스템을 통해 대기중인 통화 후 회선에서 실행을 재개 할 수 있습니다.

따라서 비동기 블록은 차단되지 않으며 대기중인 통화가 끝날 때까지 대기하지 않습니다. await 명령이 발생하면 즉시 제어가 리턴됩니다.

기본 상태 머신은 사용하지 않고 누락되지 않은 async / await를 사용하는 "마법"의 일부입니다.


2

나는 같은 질문을 염두에두고이 문제를 우연히 발견했지만, 응답을 읽은 후에는 "매력적인 마술"에 대한 언급으로 혼란스러워 보인다.

위에서 언급 한 비동기 프로그래밍에서 :

  • async키워드는 당신이 사용할 수있는 비동기 방법으로하는 방법집니다 await몸에 키워드를.
  • await키워드가 적용되어, 그것은 호출 방법을 일시 중단하고 기다려온 작업이 완료 될 때까지 수익률은 호출자에게 제어 할 수 있습니다.
  • awaitasync메소드 안에서만 사용할 수 있습니다 .

발생하는 컨텍스트가 await차단됩니까?

  • . 이는 본질적으로 실행 상황에서 알려진 상태를 유지하기위한 로컬 동기화 장벽입니다. 다른 컨텍스트 (있는 경우)는 조인되지 않습니다.

나머지 응용 프로그램은 await?

  • 신청서 작성 방법에 따라 다릅니다 . await동일한 컨텍스트에서 순차적으로 실행 되는 일련의 종속 ed 작업 인 경우 ( 일부 비동기 / 대기 동작 이해 시도 )

    await asyncCall1();
    await asyncCall2();  // waits for asyncCall1() to complete

    이런 식으로 각각 await다음 스폰 생성을 차단합니다.

    반면에 병렬로 시작된 동일한 종속 작업은 병렬로 실행되며 컨텍스트는 resp에서만 차단됩니다. await:

    Task<int> t1 = asyncCall1();
    Task<string> t2 = asyncCall2();  // runs in parallel with asyncCall1()
    int val = await t1;
    string str = await t2;  // waits for asyncCall1() to complete

    일반적으로 await현재 컨텍스트가 호출되는 외부 컨텍스트에 대한 실행 수율. 그러나 외부 컨텍스트 자체가 현재를 기다리는 await경우 동일한 컨텍스트 의 순차적 인 것과 같습니다.

따라서 async이점 을 얻으려면 여러 병렬 컨텍스트 (UI, 데이터 클라이언트 등)를 실행하도록 응용 프로그램을 디자인 한 다음 await한 컨텍스트에서 다른 컨텍스트를 실행하여 전체 응용 프로그램이 개인을 차단하지 않도록해야합니다 await.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.