Skip to content
This repository was archived by the owner on Jun 14, 2022. It is now read-only.

Latest commit

 

History

History
70 lines (51 loc) · 3.4 KB

async_await.md

File metadata and controls

70 lines (51 loc) · 3.4 KB

async/await

이거 뭔지 참 알기 어렵지요.
MS 문서 봐도 뜬구름잡는 소리 뿐입니다.
간단하게 설명해보겠습니다.

async와 일반 함수

async를 붙이면 그 함수는 ‘실행을 잠깐 중지했다가 나중에 이어서 할 수 있는’ 함수가 됩니다.
이것들을 이어서 하나의 파이버 실행 흐름을 만들려면,
콜스택 가장 마지막 단계에 있는 함수들이 아닌 이상
다들 실행을 잠깐 중지했다가 나중에 이어서 할 수 있어야 하겠죠?
그래서 파이버 안에서 실행하는 함수들은 대부분 async가 붙습니다.

참고: async는 함수 내부가 어떻게 처리될지를 지정하는 키워드이기 때문에 인터페이스에서는 async 여부를 명시할 수 없습니다. 그리고 async 함수는 중간에 실행을 중지할 수 있으므로, out/ref 인자를 쓸 수 없습니다.

요약: async는 이 함수가 실행을 중지했다가 나중에 재개할 수 있음을 의미합니다.

void / Task / Task<T>

async가 붙는 함수는 이렇게 세가지 리턴값만을 가질 수 있습니다.
호출된 함수가 실행을 잠깐 중지했을 때, 호출측에서 이것을 어떻게 처리할지의 시나리오를 생각해보면 사실 이 세가지 말고는 없습니다.

  1. void: 실행을 중지한 함수의 이후 실행을 신경쓰지 않겠다는 뜻입니다. 뭐 어디선가 마저 이어서 실행되든지 말든지…
  2. Task: 실행을 중지한 함수가 나중에 이어서 실행을 마쳤을 때, 그 흐름을 이어받아서 계속 진행할 수 있는 핸들입니다.
  3. Task<T>: Task와 비슷하게 실행 흐름을 이어받아서 계속 진행할 수 있는 핸들인데, 리턴값도 받을 수 있습니다.

요약: Task, Task<T>는 이 함수의 실행으로 인해 발생한 일이 끝났을 때 그 결과를 이어받아서 계속 진행할 수 있는 핸들입니다.

async와 Task(<T>)를 같이 쓰면

마법이 일어납니다.
그 마법이 무엇이냐!

리턴값이 Task 타입인 함수는 Task를 리턴해야 하지요?
그런데 async Task 함수에서는 Task를 리턴하지 못합니다. void 리턴인 것처럼 처리됩니다.
async Task<T> 함수에서는 Task<T> 를 리턴하는 것이 아니라 T를 리턴해야 합니다.

이해가 되시나요?
C# 컴파일러가 async Task를 인식해서 특수 처리를 해주는 것입니다.
async와 Task는 거의 언제나 같이 다닌다고 생각하시면 됩니다.

async 없이 Task만 나오는 경우가 가끔 있습니다. 함수 본체 맨 끝에 다른 함수를 호출하고 그 결과를 그대로 리턴하는 경우입니다. 이런 경우에는 async를 붙일 필요가 없이 함수의 호출 결과를 그대로 리턴하면 됩니다.

async Task FuntA()
{
    어쩌구저쩌구 다른 코드 실행 (중간에 중단하지는 않음)
    await FuncB();
}
Task FuntA()
{
    어쩌구저쩌구 다른 코드 실행 (중간에 중단하지는 않음)
    return FuncB();
}

위 두 코드는 사실상 동일하게 동작합니다.
두번째 코드가 좀더 빠르겠죠? 불필요한 await이 없으니까요.

Task가 없이 async만 나오는 경우는 없어야 합니다.
다음 문서async void 금지 에서 추가로 설명합니다.