티스토리 뷰
.NET Task.Run 사용법: 비동기 프로그래밍을 시작하는 가장 쉬운 방법
.NET 개발에서 비동기 프로그래밍은 빠질 수 없는 중요한 주제입니다.
그중에서도 Task.Run은 가장 많이 사용되는 비동기 실행 메서드 중 하나입니다.
이 메서드는 내부적으로 ThreadPool을 활용하여 작업을 큐에 넣고 실행합니다.
호출 즉시 제어를 반환하므로, 호출한 쪽 코드는 멈추지 않고 다음 작업을 이어갈 수 있습니다.
Task.Run 기본 개념
Task.Run은 .NET의 Task Parallel Library(TPL)
에서 제공하는 API로, 작업을 비동기적으로 실행하기 위해 사용됩니다. 호출 시 새로운 작업이 스레드풀에 등록되고, 그 결과는 Task
또는 Task<T>
로 반환됩니다.
기본 형태
Task.Run(() => {
// 비동기 실행할 코드
});
- 전달된 람다(또는 델리게이트)는 별도의 스레드에서 실행됩니다.
- 리턴값이 있다면
Task<T>
로 감싸져 반환됩니다.
Task.Run 사용 예시
1. 단순 실행
Task.Run(() =>
{
Console.WriteLine("백그라운드에서 실행됨");
});
Console.WriteLine("메인 스레드는 계속 진행");
출력 결과는 다음과 같습니다. 단, 순서는 보장되지 않습니다.
메인 스레드는 계속 진행
백그라운드에서 실행됨
2. 결과값 받기
Task<int> t = Task.Run(() =>
{
Thread.Sleep(1000);
return 42;
});
int result = await t; // 1초 기다린 뒤 42 반환
Console.WriteLine(result);
Task.Run
은 Task<T>
를 반환하므로, await
키워드를 사용해 결과값을 쉽게 가져올 수 있습니다.
3. UI 프로그램에서 무거운 작업 처리
WinForms나 WPF 같은 UI 기반 프로그램에서는, 무거운 작업을 메인 스레드에서 실행하면 UI가 멈춰버립니다. 이때 Task.Run
을 활용하면 사용자가 끊김 없는 경험을 할 수 있습니다.
private async void Button_Click(object sender, EventArgs e)
{
// UI가 멈추지 않음
int data = await Task.Run(() => HeavyCalculation());
MessageBox.Show($"계산 결과: {data}");
}
위 코드에서 HeavyCalculation()
은 백그라운드에서 실행되고, 끝나면 UI 스레드로 돌아와 결과를 표시합니다.
Task.Run의 특징과 장단점
- 비동기 실행: 호출 즉시 리턴하여 비동기 실행을 시작합니다.
- Task 반환:
await
,ContinueWith
등 다양한 체이닝 작업이 가능. - 에러 처리: 비동기 작업 중 발생한 예외는
Task
를 통해 전달되며,await
시 예외를 캐치할 수 있습니다. - CPU 바운드 작업에 적합: 긴 연산이나 계산에 유용합니다. (I/O 바운드 작업은
async/await
기반 비동기가 더 효율적)
Task.Run vs ThreadPool.QueueUserWorkItem
많은 분들이 Task.Run
과 ThreadPool.QueueUserWorkItem
의 차이를 헷갈려 합니다.
두 메서드 모두 내부적으로 ThreadPool을 사용하지만,
Task.Run
은 Task
객체를 반환하기 때문에 await
을 통한 결과값 처리, 예외 전파, 체이닝 등 현대적인 비동기 프로그래밍에 훨씬 적합합니다.
결론
Task.Run은 .NET에서 비동기 작업을 실행할 때 가장 쉽게 사용할 수 있는 API입니다.
단순히 작업을 던지고 싶다면 Task.Run(() => ...)
형태로,
결과값이 필요하다면 var result = await Task.Run(() => ...)
형태로 사용할 수 있습니다.
특히 CPU 바운드 연산을 백그라운드에서 처리하거나, UI 스레드를 차단하지 않고 무거운 연산을 실행해야 할 때 매우 유용합니다. 다만 I/O 바운드 시나리오에서는 async/await
와 async 메서드
자체를 사용하는 것이 더 효율적이라는 점도 기억해두세요.
비동기 프로그래밍을 처음 접하는 개발자라면, Task.Run을 시작점으로 활용해보는 것을 추천합니다.
'c#' 카테고리의 다른 글
.NET ThreadPool.QueueUserWorkItem: 비동기 작업 (0) | 2025.09.11 |
---|---|
C# Delegate 완벽 정리: Action, Func, Predicate, EventHandler 사용법 (0) | 2025.09.10 |
C# 이벤트(Event) 완벽 가이드: delegate와 event 차이, 사용법 (1) | 2025.09.10 |
[C#] DTMF 전송 방식 (In-band vs Out-of-band) 및 RTP 패킷 (0) | 2024.08.07 |
[C#] WPF Button 이미지 (0) | 2024.07.17 |
- Total
- Today
- Yesterday
- 자바 강제 형변환
- 델리게이트와 이벤트 차이
- java string int 변환
- integer 캐싱 범위
- C# Func
- spring interceptor 예제
- QueueUserWorkItem
- c#
- java 형변환 종류
- spring handlerinterceptor
- integer.valueof 사용법
- 비동기
- int to integer 변환
- C# Action
- java integer valueof parseint 차이
- C# delegate
- spring 인터셉터
- C# Predicate
- wrapper 클래스 변환
- java integer 비교 방법
- wireshark dtmf 분석
- c# 이벤트
- 스레드풀
- 비동기메서드
- 스마트 포인터
- C# 이벤트 해제
- 자바 자동 형변환 예제
- rtp 패킷 예제
- RAII
- C# EventHandler
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | 5 | 6 | |
7 | 8 | 9 | 10 | 11 | 12 | 13 |
14 | 15 | 16 | 17 | 18 | 19 | 20 |
21 | 22 | 23 | 24 | 25 | 26 | 27 |
28 | 29 | 30 |