비동기 프로그래밍 소개 (Introduction to Asynchronous Programming)
비동기 프로그래밍은 프로그램의 실행 흐름을 차단하지 않고, 시간이 오래 걸리는 작업을 동시에 처리할 수 있는 방법을 제공합니다. C#에서는 async
와 await
키워드를 사용하여 비동기 작업을 처리할 수 있습니다. 비동기 프로그래밍은 주로 I/O 작업, 웹 요청, 데이터베이스 쿼리 등 긴 작업에 적합합니다.
비동기 메서드 (Asynchronous Methods)
비동기 메서드는 async
키워드로 선언되며, 일반적으로 Task
또는 Task<T>
를 반환합니다. await
키워드를 사용하여 비동기 작업의 완료를 기다릴 수 있습니다.
예제: 기본 비동기 메서드 (Basic Asynchronous Method)
using System; using System.Threading.Tasks; namespace AsyncExample { class Program { static async Task Main(string[] args) { Console.WriteLine("Starting async operation..."); await PerformAsyncOperation(); Console.WriteLine("Async operation completed."); } static async Task PerformAsyncOperation() { // 비동기 작업 (Simulate an asynchronous operation) await Task.Delay(2000); // 2초 대기 Console.WriteLine("Operation in progress..."); } } }
이 예제에서는 PerformAsyncOperation
메서드가 2초 동안 대기하는 비동기 작업을 시뮬레이션합니다. await Task.Delay(2000)
은 2초 동안 비동기적으로 대기합니다.
비동기 메서드와 예외 처리 (Exception Handling in Asynchronous Methods)
비동기 메서드에서 예외가 발생하면 await
를 사용하는 코드 블록에서 해당 예외를 처리할 수 있습니다.
예제: 비동기 메서드에서 예외 처리 (Exception Handling in Asynchronous Methods)
using System; using System.Threading.Tasks; namespace AsyncExample { class Program { static async Task Main(string[] args) { try { await PerformAsyncOperationWithException(); } catch (Exception ex) { Console.WriteLine($"Exception caught: {ex.Message}"); } } static async Task PerformAsyncOperationWithException() { await Task.Delay(1000); throw new InvalidOperationException("Something went wrong during the async operation."); } } }
이 예제에서는 PerformAsyncOperationWithException
메서드가 예외를 발생시키며, Main
메서드에서 await
로 이 예외를 처리합니다.
비동기 작업의 병렬 처리 (Parallel Execution of Asynchronous Tasks)
여러 비동기 작업을 동시에 실행할 수 있습니다. 이는 Task.WhenAll
메서드를 사용하여 구현할 수 있습니다.
예제: 병렬 비동기 작업 (Parallel Asynchronous Tasks)
using System; using System.Threading.Tasks; namespace AsyncExample { class Program { static async Task Main(string[] args) { Task task1 = Task1(); Task task2 = Task2(); await Task.WhenAll(task1, task2); Console.WriteLine("All tasks completed."); } static async Task Task1() { await Task.Delay(2000); // 2초 대기 Console.WriteLine("Task 1 completed."); } static async Task Task2() { await Task.Delay(1000); // 1초 대기 Console.WriteLine("Task 2 completed."); } } }
이 예제에서는 Task1
과 Task2
를 동시에 실행하고, 두 작업이 모두 완료될 때까지 기다립니다. Task.WhenAll
을 사용하여 병렬로 실행되는 작업을 처리합니다.
비동기 프로그래밍과 UI (Asynchronous Programming and UI)
UI 애플리케이션에서 비동기 작업을 사용하면 UI 스레드가 차단되지 않도록 할 수 있습니다. 이는 주로 WPF 또는 Windows Forms 애플리케이션에서 사용됩니다.
예제: 비동기 작업과 UI (Asynchronous Tasks and UI)
using System; using System.Threading.Tasks; using System.Windows.Forms; namespace AsyncWinFormsExample { public partial class MainForm : Form { public MainForm() { InitializeComponent(); } private async void buttonStart_Click(object sender, EventArgs e) { buttonStart.Enabled = false; await LongRunningOperation(); buttonStart.Enabled = true; } private async Task LongRunningOperation() { await Task.Delay(3000); // 3초 대기 MessageBox.Show("Operation completed."); } } }
이 예제에서는 버튼 클릭 시 비동기 작업을 수행하며, 작업이 완료된 후 버튼을 다시 활성화합니다. UI 스레드가 차단되지 않도록 비동기 작업을 사용합니다.
비동기 스트림 (Asynchronous Streams)
C# 8.0부터는 비동기 스트림을 지원합니다. IAsyncEnumerable<T>
와 await foreach
를 사용하여 비동기적으로 데이터를 스트리밍할 수 있습니다.
예제: 비동기 스트림 사용 (Using Asynchronous Streams)
using System; using System.Collections.Generic; using System.Threading.Tasks; namespace AsyncStreamsExample { 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 = 0; i < 5; i++) { await Task.Delay(1000); // 1초 대기 yield return i; } } } }
이 예제에서는 GenerateNumbersAsync
메서드가 1초 간격으로 숫자를 생성하고, await foreach
를 사용하여 비동기 스트림으로 데이터를 읽어옵니다.
비동기 프로그래밍 종합 예제 (Comprehensive Example of Asynchronous Programming)
using System; using System.Net.Http; using System.Threading.Tasks; namespace AsyncExample { class Program { static async Task Main(string[] args) { Console.WriteLine("Starting web request..."); string result = await FetchWebContentAsync("https://www.example.com"); Console.WriteLine("Web request completed."); Console.WriteLine($"Content length: {result.Length} characters"); } static async Task<string> FetchWebContentAsync(string url) { using (HttpClient client = new HttpClient()) { string content = await client.GetStringAsync(url); return content; } } } }
이 종합 예제에서는 FetchWebContentAsync
메서드를 사용하여 비동기적으로 웹 페이지의 내용을 가져오고, 내용을 콘솔에 출력합니다. HttpClient
를 사용하여 비동기 HTTP 요청을 수행합니다.
결론 (Conclusion)
비동기 프로그래밍은 현대 애플리케이션에서 중요한 부분을 차지하며, C#에서는 async
와 await
키워드를 통해 비동기 작업을 쉽게 처리할 수 있습니다. 비동기 작업을 통해 UI 스레드를 차단하지 않고, 효율적으로 긴 작업을 처리하며, 다양한 비동기 연산자와 패턴을 활용할 수 있습니다. 비동기 스트림과 같은 최신 기능을 사용하여 데이터 스트리밍을 비동기적으로 처리하는 것도 가능합니다.