반응형
이 코드는 C#에서 태스크(Task)를 사용하여 멀티스레드 환경에서 연산을 수행하는 기본적인 예제를 보여줍니다. 코드를 분석하고 스레드 풀(Thread Pool)과 메인 스레드에서 실행되는 태스크의 차이를 교육용으로 설명하겠습니다.
코드 구성 및 주요 흐름
1. CreateTask 메서드
static Task<int> CreateTask(string name)
{
return new Task<int>(() => TaskMethod(name));
}
- 이 메서드는 태스크를 생성합니다.
- 태스크는 Task<int> 타입으로 반환되며, 내부적으로 TaskMethod를 실행합니다.
- 태스크는 생성만 되며, 실행은 호출자가 결정합니다 (Start()나 RunSynchronously()를 호출해야 실행됩니다).
2. TaskMethod 메서드
static int TaskMethod(string name)
{
Console.WriteLine("Task '{0}' is running on a thread id {1}. Is thread pool thread: {2}",
name,
Thread.CurrentThread.ManagedThreadId,
Thread.CurrentThread.IsThreadPoolThread);
Thread.Sleep(TimeSpan.FromSeconds(2));
return 42;
}
- 이 메서드는 태스크가 수행할 작업입니다.
- 출력 내용:
- 현재 실행 중인 스레드의 ID (Thread.ManagedThreadId).
- 실행 중인 스레드가 **스레드 풀(Thread Pool)**에서 실행되는지 여부 (Thread.IsThreadPoolThread).
- 태스크는 2초간 멈춘 후 정수 42를 반환합니다.
3. Main 메서드
static void Main(string[] args)
{
TaskMethod("Main Thread Task");
Task<int> task = CreateTask("Task 1");
task.Start();
int result = task.Result;
Console.WriteLine("Result is: {0}", result);
task = CreateTask("Task 2");
task.RunSynchronously();
result = task.Result;
Console.WriteLine("Result is: {0}", result);
task = CreateTask("Task 3");
task.Start();
while (!task.IsCompleted)
{
Console.WriteLine(task.Status);
Thread.Sleep(TimeSpan.FromSeconds(0.5));
}
Console.WriteLine(task.Status);
result = task.Result;
Console.WriteLine("Result is: {0}", result);
}
- 이 메서드는 태스크 생성, 실행, 결과 확인의 여러 시나리오를 보여줍니다.
- 각 시나리오를 순서대로 살펴보겠습니다.
시나리오 분석
1. 직접 호출 (TaskMethod)
TaskMethod("Main Thread Task");
- 동작:
- TaskMethod가 태스크 없이 직접 호출됩니다.
- 메인 스레드에서 실행되며, 스레드 풀과 관련이 없습니다.
- 출력 예시:
Task 'Main Thread Task' is running on a thread id 1. Is thread pool thread: False
2. 태스크 생성 후 Start로 실행
Task<int> task = CreateTask("Task 1");
task.Start();
int result = task.Result;
Console.WriteLine("Result is: {0}", result);
- 동작:
- 태스크 Task 1이 생성되고 Start()로 실행됩니다.
- 실행은 스레드 풀에서 이루어집니다.
- task.Result는 태스크의 결과를 가져옵니다. 결과를 가져올 때까지 호출자는 대기합니다.
- 출력 예시:
Task 'Task 1' is running on a thread id 4. Is thread pool thread: True Result is: 42
3. 태스크를 동기적으로 실행 (RunSynchronously)
task = CreateTask("Task 2");
task.RunSynchronously();
result = task.Result;
Console.WriteLine("Result is: {0}", result);
- 동작:
- RunSynchronously()는 태스크를 현재 스레드(메인 스레드)에서 실행합니다.
- 스레드 풀을 사용하지 않고 메인 스레드에서 실행됩니다.
- 동기적으로 실행되므로 호출자가 태스크 종료를 기다릴 필요가 없습니다.
- 출력 예시:
Task 'Task 2' is running on a thread id 1. Is thread pool thread: False Result is: 42
4. 태스크 상태 확인
task = CreateTask("Task 3");
task.Start();
while (!task.IsCompleted)
{
Console.WriteLine(task.Status);
Thread.Sleep(TimeSpan.FromSeconds(0.5));
}
Console.WriteLine(task.Status);
result = task.Result;
Console.WriteLine("Result is: {0}", result);
- 동작:
- Task 3을 실행하고 상태를 확인하며, 완료될 때까지 루프에서 대기합니다.
- task.Status는 태스크 상태를 나타냅니다. 상태는 다음 중 하나일 수 있습니다:
- WaitingToRun: 실행 대기 중.
- Running: 실행 중.
- RanToCompletion: 완료됨.
- 출력 예시:
WaitingToRun Running Running RanToCompletion Result is: 42
스레드 풀과 메인 스레드의 차이점
특징 스레드 풀(Thread Pool) 메인 스레드(Main Thread)
실행 환경 | Task.Start() 또는 Task.Run() 사용 시 실행. | 프로그램의 주 실행 스레드. |
스레드 ID | 스레드 풀에서 생성된 스레드 ID 사용. | 항상 ID 1. |
IsThreadPoolThread | True. | False. |
사용 목적 | 백그라운드 태스크 처리, 비동기 작업. | UI 업데이트 및 주요 작업 흐름 관리. |
실행 방식 | 스레드 풀이 관리하며, 비동기적으로 실행. | 동기적 실행, 현재 스레드에서 수행. |
코드의 주요 포인트
- 태스크 생성과 실행:
- 태스크는 생성 후 명시적으로 Start()나 RunSynchronously()를 호출해야 실행됩니다.
- 스레드 풀과 메인 스레드:
- 태스크는 스레드 풀에서 실행될 수 있지만, RunSynchronously로 메인 스레드에서 실행 가능.
- 태스크 상태 관리:
- task.Status를 통해 태스크의 상태를 실시간으로 확인할 수 있습니다.
- 결과 처리:
- task.Result는 태스크 결과를 반환하지만, 태스크가 완료되지 않은 경우 대기합니다.
추가 학습
- async/await 기반 비동기 프로그래밍:
- 태스크와 잘 어우러지는 C# 비동기 프로그래밍 패턴.
- 병렬 처리:
- Task.WhenAll 또는 Task.WhenAny를 사용하여 여러 태스크를 병렬로 실행.
이 코드는 태스크의 동작 원리를 이해하는 데 유용한 예제입니다. 추가적으로 궁금한 점이 있다면 언제든 질문해주세요! 😊
반응형
'C# > 쓰레드' 카테고리의 다른 글
1. C# 스레드 생성과 병렬 처리 이해 (2) | 2025.01.24 |
---|---|
4. 태스크 병렬 라이브러리 (0) | 2025.01.20 |
C# 태스크(Task)와 비동기 프로그래밍: 생성, 연속 작업, 부모-자식 관계 이해 (1) | 2025.01.20 |
C# TPL: 태스크 생성 방식과 실행 흐름 완벽 이해 (1) | 2025.01.17 |
C# `Thread`와 `ThreadPool`의 차이점 및 델리게이트 비동기 호출 이해 (17) | 2025.01.16 |
C# 스레드풀(Thread Pool): 개념, 사용법, 및 예제 코드 설명 (1) | 2025.01.16 |
C# SemaphoreSlim: 멀티스레드 리소스 접근 제어 예제와 설명 (2) | 2025.01.16 |
C# 스레드 제어: Semaphore와 SemaphoreSlim의 차이와 사용법 (2) | 2025.01.16 |