[OSSCA] #63 엔드포인트 리팩토링 - 4. 그것이 알고싶다 : async, await

뚜비·2022년 9월 6일
0

2022 OSSCA

목록 보기
13/14
post-thumbnail

2022 오픈소스 컨트리뷰션 아카데미 "NHN Toast Power Platform Connector" Masters에 참여하면서 배운 내용을 기록하였습니다.



🤔 그것이 알고싶다 : async, await

❓❓ 서론 - 나의 문제 해결 과정..

코드 리팩토링 중 쿼리 부분에서 다음과 같은 에러가 발생했다.


참고 링크를 보면서 GetAwaiter().GetResult() 를 이용하여 해결한 줄 알았는데....


그렇다..! 바로 데드락(교착상태)에 빠질 수 있다는 것!


참고링크2에도 GetAwaiter().GetResult()가 교착 상태 및 스레드 풀 기아 문제가 발생할 수 있다고 언급되어 있다. 고민 끝에 await keyword를 추가했더니 잘 되는 것이 아닌가!!



❓❗ 본론 - async, await

await keyword가 추가되니 문제가 해결되었는지를 이해하기 위해서는 먼저 async와 await에 대한 이해가 필요했다. await operator (C# reference) 문서와 예원 언니의 도움을 받아 이해했다

동기와 비동기

동기(synchronous)는 요청과 그 결과가 동시에 일어난다는 약속이다. 즉 반드시 요청한 자리에서 결과가 주어져야 해서 순서에 맞춰 진행된다. 하지만 여러 요청을 동시에 처리할 수 없다.
비동기는 요청과 결과가 동시에 일어나지 않을 거라는 약속이다. 즉, 동시에 여러 요청을 처리할 수 있다는 의미이다. (한 요청의 결과가 나오지 않았음에도 불구하고 다른 요청을 진행할 수 있다.)


아래 코드를 보자
using System;
using System.Net.Http;
using System.Threading.Tasks;

public class AwaitOperator
{
    public static async Task Main()
    {
        Task<int> downloading = DownloadDocsMainPageAsync();
        Console.WriteLine($"{nameof(Main)}: Launched downloading.");

        int bytesLoaded = await downloading;
        Console.WriteLine($"{nameof(Main)}: Downloaded {bytesLoaded} bytes.");
    }

    private static async Task<int> DownloadDocsMainPageAsync()
    {
        Console.WriteLine($"{nameof(DownloadDocsMainPageAsync)}: About to start downloading.");

        var client = new HttpClient();
        byte[] content = await client.GetByteArrayAsync("https://docs.microsoft.com/en-us/");

        Console.WriteLine($"{nameof(DownloadDocsMainPageAsync)}: Finished downloading.");
        return content.Length;
    }
}
// Output similar to:
// DownloadDocsMainPageAsync: About to start downloading.
// Main: Launched downloading.
// DownloadDocsMainPageAsync: Finished downloading.
// Main: Downloaded 27700 bytes.

AwaitOperator 안에는 Main 메소드와 DownloadDocsMainPageAsync 메소드가 존재하는데 두 메소드는 비동기로 움직인다. Main 메소드를 호출하면 그 안에 DownloadDocsMainPageAsync 메소드가 호출되고 각 메소드는 동시에 처리할 수 있게 된다.

이때 Main 메소드에는 await downloading이 있는데 DownloadDocsMainPageAsync 메소드가 모두 처리 되어 결과값을 받을 때까지 대기한 후 실행하게 된다.

또한 DownloadDocsMainPageAsync 메소드에도 await client.GetByteArrayAsync 즉, await 키워드를 볼 수 있는데 이는 GetByteArrayAsync가 모든 byte들을 얻을 때까지 대기하고 남은 DownloadDocsMainPageAsync를 실행하게 된다.

즉 await은 비동기 메소드 안에서 반드시 결과값을 받고 실행해야 하는 연산이 있을 때, 결과값을 받을 때까지 block 상태로 만들어주는 키워드라고 이해했다.



❗❗ 결론

queries type은 System.Runtime.CompilerServices.ConfiguredTaskAwaitable< T > 인데 req.To< T >에서 T 값이 들어오고 메소드의 결과값이 return될 때의 queries type은 BaseRequestQuries가 된다. 즉 await keyword를 통해 예상되는 queries의 type을 BaseRequestQuries임을 명시할 수 있다!

야무지게 공유도 했다!!

profile
SW Engineer 꿈나무 / 자의식이 있는 컴퓨터

0개의 댓글