User user = await GetUserAsync(); // 결과값이 필요한 경우 /* 비동기 작업 자체를 일단 가지고 있다가 나중에 결과를 받을 경우, 여기서 task는 User를 가지고 있는건 아님 User를 가져오는 비동기 작업을 나타내는 객체임 */ Task<User> task = GetUserAsync(); Task<Item> itemTask = GetItemAsync(); Task<Rank> rankTask = GetRankAsync(); User user2 = await task; // 이제 결과가 필요해졌을 때 Item item = await itemTask; Rank rank = await rankTask;
6.1 WhenAll()
여러 비동기 작업을 모두 기다릴 때 사용한다. JS Promise.all하고 같음
1 2 3 4 5 6 7
var userTask = GetUserFromDbAsync(); var rankingTask = GetRankingFromRedisAsync();
await Task.WhenAll(userTask, rankingTask);
var user = await userTask; var ranking = await rankingTask;
1 2 3 4
DB 조회 ───────── 100ms Redis 조회 ───────── 100ms ↓ 총 100ms
GetUserAsync() 호출 ↓ async 메서드 실행 ↓ "1" 출력 ↓ GetFromDBAsync() 호출 ↓ Task<User> 반환 ↓ await에서 Task 상태 확인 │ ├─────────────── Task가 이미 완료됨 ───────────────┐ │ │ │ ↓ │ 바로 다음 코드 실행 │ │ │ ↓ │ "2" 출력 │ │ │ ↓ │ return │ └─────────────── Task가 아직 실행 중 ──────────────┐ │ ↓ State Machine에 현재 상태 저장 ↓ continuation 등록 ↓ GetUserAsync()가 Task를 반환 ↓ Thread는 다른 작업 수행 ↓ DB 작업 완료 ↓ continuation 실행 ↓ State Machine 상태 복원 ↓ await 다음 코드 실행 ↓ "2" 출력 ↓ return