본문 바로가기
카테고리 없음

C#의 Thread 종류와 동기식/비동기식 활용 방법

by tasiklee 2025. 2. 14.

C#의 Thread 종류와 동기식/비동기식 활용 방법

C#에서 멀티스레딩은 성능 최적화와 비동기 작업을 수행하는 데 중요한 역할을 합니다. 기본적으로 C#에서 스레드를 다루는 방법에는 여러 가지가 있으며, 각 방식은 특정한 상황에 따라 적절하게 선택해야 합니다. 이번 글에서는 C#의 주요 스레드 종류와 동기식/비동기식 처리 방식에 대해 알아보겠습니다.

1. C#의 Thread 종류

C#에서 멀티스레드를 구현하는 방식은 크게 다음과 같이 나눌 수 있습니다.

1) Thread 클래스

.NET에서 기본적으로 제공하는 Thread 클래스를 이용하면 직접 스레드를 생성하고 관리할 수 있습니다.

sing System;
using System.Threading;

class Program
{
    static void Main() // 메인함수 ~
    {
        Thread thread = new Thread(Work); // thread를 선언하기
        thread.Start(); // 선언한 trhead 시작

        for (int i = 0; i < 5; i++)
        {
            Console.WriteLine("Main Thread 실행 중...");
            Thread.Sleep(500);
        }
    }

    static void Work()
    {
        for (int i = 0; i < 5; i++)
        {
            Console.WriteLine("Worker Thread 실행 중...");
            Thread.Sleep(500);
        }
    }
}​

이 방식은 직접적인 스레드 관리를 할 수 있다는 장점이 있지만, 수동으로 생성하고 종료해야 하므로 다소 번거롭습니다.

2) ThreadPool

ThreadPool은 시스템에서 관리하는 스레드 풀을 사용하여 백그라운드 작업을 실행할 수 있도록 합니다.

using System;
using System.Threading;

class Program
{
    static void Main()
    {
        ThreadPool.QueueUserWorkItem(Work);

        Console.WriteLine("Main Thread 실행 중...");
        Thread.Sleep(2000);
    }

    static void Work(object state)
    {
        Console.WriteLine("ThreadPool Worker 실행 중...");
    }
}​

이 방식은 스레드를 직접 생성하지 않고 시스템이 관리하는 스레드 풀을 활용하여 간편하게 사용할 수 있습니다.

3) Task (TPL)

비동기 프로그래밍이 중요해짐에 따라 C#에서는 Task를 활용한 멀티스레딩이 일반적입니다.

using System;
using System.Threading.Tasks;

class Program
{
    static async Task Main()
    {
        Task task = Task.Run(() => 
        {
            Console.WriteLine("Task 실행 중...");
        });

        await task;
        Console.WriteLine("작업 완료");
    }
}

Task는 비동기 작업을 효율적으로 실행할 수 있으며, 병렬 처리나 데이터 처리에 적합합니다.

4) async와 await

비동기 방식의 핵심 기능인 async와 await를 활용하면 코드의 가독성을 높일 수 있습니다.

using System;
using System.Threading.Tasks;

class Program
{
    static async Task Main()
    {
        await DoWorkAsync();
        Console.WriteLine("모든 작업 완료"); // 작업 완료 로그 콘솔로 띄우기
    }

    static async Task DoWorkAsync()
    {
        await Task.Delay(1000); // thread delay 주고
        Console.WriteLine("비동기 작업 실행 완료"); // 비동기 완료 신호 주기!
    }
}

저는 비동기 방법은 보통 백그라운드에서 함수를 실행시키기 위해 사용합니다.

비동기 메서드를 쉽게 정의하고 호출할 수 있도록 해주게 되죠!


2. 동기식 : Synchronous vs 비동기식 : Asynchronous

멀티스레딩(Multi Thread)을 이해하려면 먼저 동기식과 비동기식의 차이를 이해하는 것이 포인트입니다!

1) 동기식(Synchronous)

동기식 방식은 코드가 순차적으로 실행되게 되고, 이전 작업이 완료되어야 다음 작업이 실행됩니다~!

using System;

class Program
{
    static void Main()
    {
        Console.WriteLine("작업 시작");
        DoWork();
        Console.WriteLine("작업 완료");
    }

    static void DoWork()
    {
        System.Threading.Thread.Sleep(2000);  
        Console.WriteLine("동기 작업 수행 중...");
    }
}

이 방식은 단순하지만, 실행 중인 작업이 완료될 때까지 다른 작업을 수행할 수 없다는 단점이 있습니다.

활용 사례

  • 순차적으로 실행해야 하는 작업 (예: 파일 입출력, 데이터베이스 트랜잭션)
  • 즉각적인 응답이 필요하지 않은 경우

2) 비동기식(Asynchronous)

비동기 방식에서는 특정 작업이 실행되는 동안 다른 작업을 수행할 수 있습니다.

using System;
using System.Threading.Tasks;

class Program
{
    static async Task Main()
    {
        Console.WriteLine("작업 시작");
        await DoWorkAsync();
        Console.WriteLine("작업 완료");
    }

    static async Task DoWorkAsync()
    {
        await Task.Delay(2000);
        Console.WriteLine("비동기 작업 수행 중...");
    }
}

비동기 작업을 수행하는 동안 메인 스레드는 다른 작업을 수행할 수 있어 효율적입니다.

활용 사례

  • 네트워크 요청 (예: HTTP API 호출)
  • 사용자 인터페이스(UI) 작업 (예: 버튼 클릭 이벤트 처리)
  • 긴 연산 작업 (예: 대용량 데이터 처리)

3. 정리

구분방식주요 특징활용 사례

Thread 명시적 생성 직접 생성 및 관리 필요 병렬 처리, 백그라운드 작업
ThreadPool 시스템 관리 자동 관리, 단순한 구조 짧은 주기의 반복 작업
Task TPL 지원 비동기 작업에 최적화 병렬 처리, CPU 집중 작업
async/await 비동기 처리 가독성 향상, 동시 작업 가능 네트워크 요청, UI 응답성 개선
  • **동기식(Synchronous)**은 순차적으로 실행되며, 작업이 완료될 때까지 대기합니다.
  • **비동기식(Asynchronous)**은 다른 작업을 병렬로 수행할 수 있어 응답성을 높일 수 있습니다.

C#에서 멀티스레딩을 활용할 때는 상황에 맞게 적절한 방식(Thread, ThreadPool, Task, async/await)을 선택하는 것이 중요합니다. 특히, 성능과 가독성을 고려해 Task와 async/await를 활용하는 것이 현대적인 C# 개발에서는 일반적입니다.

이제 실무에서 적절한 멀티스레딩 기법을 선택하여 효율적인 프로그램을 작성해 보세요! 🚀