IMCAT.DEV
로그인 가입
C# 중급 비동기

C# 비동기 프로그래밍(async/await)

C# 비동기 프로그래밍(async/await) — 중급

비동기 프로그래밍(async/await)

1. 도입 (왜 배워야 하는가)

비동기 프로그래밍은 현대 소프트웨어 개발에서 필수적인 기술입니다. 특히 웹 애플리케이션이나 API 서버와 같이 많은 요청을 처리해야 하는 환경에서 비동기를 잘 활용하면 성능을 크게 향상시킬 수 있습니다.

비동기를 사용하지 않으면 사용자가 요청을 보낸 후 결과가 돌아올 때까지 애플리케이션이 멈추게 되어, 사용자 경험이 저하되고 시스템 자원도 비효율적으로 사용될 수 있습니다. 예를 들어, 쇼핑몰에서 사용자가 상품을 검색할 때 비동기를 사용하지 않으면 검색이 완료될 때까지 다른 작업을 할 수 없습니다.

비동기 프로그래밍을 이해하지 못하면 성능 저하와 사용자 불만족을 초래할 수 있습니다.

2. 핵심 개념 설명

비동기(Asynchronous)

비동기 프로그래밍은 작업을 수행하는 동안 다른 작업을 동시에 처리할 수 있도록 해줍니다. 마치 요리사가 음식을 준비하는 동안 손님이 대기하는 것과 같습니다. 요리사가 음식을 조리하는 동안 다른 손님을 맞이할 수 있습니다.

await

await 키워드는 비동기 메서드 내에서 사용되어, 비동기 작업이 완료될 때까지 기다리게 합니다. 이는 마치 요리사가 음식을 조리하고 있는 동안, 다른 손님을 맞이하면서 음식이 준비되면 바로 제공하는 것과 같습니다.

async

async 키워드는 메서드가 비동기적으로 실행될 수 있음을 나타냅니다. 이는 요리사가 여러 가지 요리를 동시에 준비할 수 있도록 도와주는 주방장과 같습니다.
용어설명
async비동기 메서드임을 나타내는 키워드
await비동기 작업이 완료될 때까지 대기하는 키워드

3. 기본 코드 예제

비동기 메서드를 정의하고 호출하는 기본적인 예제를 살펴보겠습니다.

using System;
using System.Net.Http;
using System.Threading.Tasks;

class Program
{
    static async Task Main(string[] args)
    {
        Console.WriteLine("데이터를 가져오는 중...");
        string data = await FetchDataAsync();
        Console.WriteLine(data);
    }

    static async Task<string> FetchDataAsync()
    {
        using HttpClient client = new HttpClient();
        string result = await client.GetStringAsync("https://jsonplaceholder.typicode.com/posts/1");
        return result;
    }
}

실행 결과:

데이터를 가져오는 중...
{ "userId": 1, "id": 1, "title": "sunt aut facere repellat provident occaecati excepturi optio reprehenderit", "body": "quia et suscipit\nsuscipit ..."}

코드 한 줄씩 동작 설명:

  1. static async Task Main(string[] args) : 비동기 메인 메서드를 정의합니다.
  2. Console.WriteLine("데이터를 가져오는 중..."); : 데이터 요청을 시작함을 알립니다.
  3. string data = await FetchDataAsync(); : FetchDataAsync 메서드를 호출하며, 완료될 때까지 대기합니다.
  4. static async Task<string> FetchDataAsync() : 비동기적으로 데이터를 가져오는 메서드를 정의합니다.
  5. using HttpClient client = new HttpClient(); : HTTP 클라이언트를 생성합니다.
  6. string result = await client.GetStringAsync(...); : 비동기적으로 데이터를 가져오며, 완료될 때까지 대기합니다.
  7. return result; : 가져온 데이터를 반환합니다.
  8. 4. 실전 활용 예제

    1. 쇼핑몰 장바구니 구현

    쇼핑몰에서 장바구니에 담긴 상품 정보를 비동기적으로 가져오는 예제입니다.

    static async Task<List<Product>> GetCartItemsAsync()
    {
        using HttpClient client = new HttpClient();
        string json = await client.GetStringAsync("https://api.example.com/cart");
        return JsonConvert.DeserializeObject<List<Product>>(json);
    }

    2. 데이터베이스 쿼리

    데이터베이스에서 비동기적으로 데이터를 조회하는 예제입니다.

    static async Task<List<User>> GetUsersAsync()
    {
        using SqlConnection connection = new SqlConnection("connection_string");
        await connection.OpenAsync();
        SqlCommand command = new SqlCommand("SELECT * FROM Users", connection);
        using SqlDataReader reader = await command.ExecuteReaderAsync();
        List<User> users = new List<User>();
        while (await reader.ReadAsync())
        {
            users.Add(new User { Id = reader.GetInt32(0), Name = reader.GetString(1) });
        }
        return users;
    }

    5. 흔한 실수와 주의사항

    1. async 메서드에서 await를 사용하지 않음

    • 잘못된 코드:
    •     static async Task<string> FetchDataAsync()
          {
              string result = client.GetStringAsync("url"); // await 누락
              return result;
          }
    • 올바른 코드:
    •     static async Task<string> FetchDataAsync()
          {
              string result = await client.GetStringAsync("url");
              return result;
          }

      2. async 메서드에서 예외 처리 부족

    • 잘못된 코드:
    •     static async Task<string> FetchDataAsync()
          {
              string result = await client.GetStringAsync("url");
          }
    • 올바른 코드:
    •     static async Task<string> FetchDataAsync()
          {
              try
              {
                  string result = await client.GetStringAsync("url");
                  return result;
              }
              catch (Exception ex)
              {
                  Console.WriteLine($"오류 발생: {ex.Message}");
                  return null;
              }
          }

      6. 정리

    • 비동기 프로그래밍은 사용자 경험을 개선하고 성능을 향상시킵니다.
    • async와 await 키워드를 통해 비동기 메서드를 쉽게 작성할 수 있습니다.
    • 비동기 메서드에서 예외 처리를 신경 써야 합니다.
    • 다음에 학습하면 좋은 주제: Task Parallel Library (TPL), 비동기 스트림(Async Streams), CancellationToken.

비동기 프로그래밍을 통해 더 나은 성능과 사용자 경험을 제공할 수 있도록 연습해 보세요!