프로그래밍 언어/C#

C# Task와 Task<T>를 활용한 비동기 프로그래밍 - C# 22

eco7T 2024. 11. 14. 11:27
반응형

이번 글에서는 C#의 비동기 프로그래밍에서 핵심적인 역할을 하는 Task와 Task<T>의 사용법, 그리고 비동기 스트림(Async Streams)에 대해 정리합니다. 비동기 프로그래밍의 원리를 이해하고 실제로 활용 가능한 코드를 작성할 수 있도록 예시를 제시하며 이해할 수 있도록 설명하려 합니다.

C# Task와 Task&lt;T&gt;를 활용한 비동기 프로그래밍
C# Task와 Task<T>를 활용한 비동기 프로그래밍

 

C# Task 및 Task<T> 그리고 비동기 스트림

비동기 프로그래밍은 동시에 여러 작업을 처리할 수 있는 프로그래밍 방법입니다. 즉, 작업이 끝나기를 기다리지 않고 다른 작업을 계속해서 진행할 수 있게 해 줍니다. 예를 들어, 파일을 다운로드하는 동안 UI가 응답하지 않는 문제를 해결하기 위해 비동기 프로그래밍을 사용합니다. 이렇게 하면 다운로드가 완료될 때까지 사용자가 다른 작업을 계속 진행할 수 있게 됩니다.

 

반응형

 

  Task 및 Task<T>의 사용법

Task는 비동기 작업을 나타내는 객체입니다. 간단히 말해서, Task는 우리가 시작한 비동기 작업이 언제 끝날지 알려주는 일종의 약속(Promise)라고 생각할 수 있습니다. 비동기 작업이 끝나면 Task가 완료되었다고 알려주는 방식입니다.

 

Task<T>는 반환값이 있는 비동기 작업을 나타냅니다. 여기서 <T>는 반환값의 자료형을 의미합니다. 예를 들어, Task<int>는 정수를 반환하는 비동기 작업을 뜻합니다.

 

Task를 사용한 비동기 함수

아래는 Task를 사용하여 비동기 작업을 구현하는 예시입니다. 간단한 딜레이 작업을 비동기로 처리하고, 그 동안 다른 작업을 처리할 수 있는 모습을 보여줍니다.

using System; using System.Threading.Tasks; class Program { static async Task Main(string[] args) { Console.WriteLine("작업 시작"); await DoSomethingAsync(); Console.WriteLine("작업 완료"); } static async Task DoSomethingAsync() { Console.WriteLine("3초 기다리는 중..."); await Task.Delay(3000); // 3초 대기 Console.WriteLine("3초 기다림 완료"); } }

위 코드에서 DoSomethingAsync 메서드는 3초 동안 기다리는 비동기 작업을 수행합니다. await 키워드는 Task가 완료될 때까지 기다린다는 의미입니다. 이렇게 await을 사용하면, 메서드의 나머지 부분이 Task가 완료된 후에 실행됩니다.

 

 

 

Task<T>를 사용하여 결과 반환하기

이번에는 Task<T>를 사용하여 비동기 작업이 결과를 반환하는 예제를 보겠습니다.

using System; using System.Threading.Tasks; class Program { static async Task Main(string[] args) { Console.WriteLine("계산 시작"); int result = await CalculateSumAsync(5, 10); Console.WriteLine($"계산 결과: {result}"); } static async Task<int> CalculateSumAsync(int a, int b) { await Task.Delay(2000); // 2초 대기 return a + b; } }

위 예시에서,

  • CalculateSumAsync 메서드는 2초 동안 기다린 후에 두 숫자의 합을 반환합니다.
  • Tas<int>는 결과로 정수 타입의 값을 반환하는 비동기 작업을 의미합니다.
  • await을 사용하여 해당 작업이 끝난 후 결과를 얻습니다.

 

비동기 스트림(Async Streams)

비동기 스트림은 C# 8.0부터 도입된 기능으로, 데이터를 **비동기로 하나씩 읽어올 수 있는 기능**을 제공합니다. 예를 들어, 서버에서 대량의 데이터를 스트리밍으로 받아야 할 때, 모든 데이터를 한 번에 받는 대신 데이터가 도착하는 대로 하나씩 처리할 수 있습니다.

비동기 스트림을 사용하기 위해서는 IAsyncEnumerable<T>await foreach를 사용합니다.

 

다음은 비동기 스트림을 사용하는 간단한 예시입니다. 1초마다 숫자를 하나씩 비동기로 출력하는 코드입니다.

using System; using System.Collections.Generic; using System.Threading.Tasks; class Program { static async Task Main(string[] args) { await foreach (var number in GenerateNumbersAsync()) { Console.WriteLine($"받은 숫자: {number}"); } } static async IAsyncEnumerable<int> GenerateNumbersAsync() { for (int i = 1; i <= 5; i++) { await Task.Delay(1000); // 1초 대기 yield return i; } } }

위 코드에서, GenerateNumbersAsync 메서드는 1초마다 숫자를 하나씩 생성하여 반환합니다. await foreach를 사용하여 비동기 스트림에서 데이터를 하나씩 받아올 수 있습니다. 이를 통해 대량의 데이터를 효율적으로 처리할 수 있습니다.

 

오늘은 Task와 Task<T>를 사용하여 비동기 작업을 처리하는 방법과 비동기 스트림을 통해 데이터를 비동기로 효율적으로 처리하는 방법에 대해 살펴봤습니다. 중요한 점은 비동기 프로그래밍을 사용하면 프로그램이 긴 시간 동안 대기 상태에 있을 때도 다른 작업을 계속해서 수행할 수 있다는 것입니다. 

반응형