Home C# [C#] 비동기 메서드 Wait(), lock(), …

[C#] 비동기 메서드 Wait(), lock(), …

by DUBUKIMCH

C#에서 Task.Delay().Wait(), ContinueWith(), lock {}, AutoResetEvent는 모두 비동기 처리나 스레드 동기화와 관련된 중요한 요소입니다. 각각의 기능과 예제를 아래와 같이 정리해 드립니다.


✅ 1. Task.Delay().Wait()

✔️ 설명:

Task.Delay(시간)은 일정 시간(ms) 동안 비동기적으로 대기하는 Task를 반환합니다.
.Wait()을 붙이면 동기적으로 기다립니다.

✔️ 예시:

Console.WriteLine("1초 대기 시작");
Task.Delay(1000).Wait(); // 동기 대기
Console.WriteLine("1초 대기 완료");

✅ 2. Task.ContinueWith()

✔️ 설명:

Task 완료 후 후속 작업을 연결할 때 사용합니다.
(비동기 콜백 형태로 실행됩니다.)

✔️ 예시:

Console.WriteLine("작업 시작");

Task.Delay(1000).ContinueWith((t) =>
{
    Console.WriteLine("1초 후 이어서 실행됨");
});

Console.WriteLine("작업 요청 완료");
Task.Delay(2000).Wait(); // 프로그램 종료 방지용 대기

✅ 3. lock {}

✔️ 설명:

여러 스레드가 동시에 공유 자원에 접근할 때 **경쟁 조건(race condition)**을 방지하기 위해 사용합니다.

✔️ 예시:

class Counter
{
    private int count = 0;
    private object lockObj = new object();

    public void Increment()
    {
        lock (lockObj)
        {
            count++;
        }
    }

    public int GetCount() => count;
}

이 경우 여러 스레드가 동시에 Increment()를 호출해도 count++는 안전하게 수행됩니다.


✅ 4. AutoResetEvent

✔️ 설명:

AutoResetEvent스레드 간의 신호 전달에 사용됩니다.
하나의 스레드가 작업을 마친 후 다른 스레드에게 **”이제 시작해”**라고 신호를 줄 수 있습니다.

✔️ 예시:

AutoResetEvent autoEvent = new AutoResetEvent(false);

void ThreadA()
{
    Console.WriteLine("Thread A 작업 중...");
    Thread.Sleep(1000);
    Console.WriteLine("Thread A 완료, 신호 보냄");
    autoEvent.Set(); // 대기 중인 스레드에게 신호
}

void ThreadB()
{
    Console.WriteLine("Thread B 대기 중...");
    autoEvent.WaitOne(); // 신호 올 때까지 대기
    Console.WriteLine("Thread B 실행 시작");
}

// 실행 예
new Thread(ThreadA).Start();
new Thread(ThreadB).Start();

🧩 종합 예제: Wait, ContinueWith, lock, AutoResetEvent 조합

class Program
{
    static int sharedValue = 0;
    static object locker = new object();
    static AutoResetEvent autoEvent = new AutoResetEvent(false);

    static void Main()
    {
        Console.WriteLine("Main 시작");

        Task.Run(() =>
        {
            Console.WriteLine("작업 스레드 대기 시작");
            Task.Delay(500).Wait(); // 동기 대기
            lock (locker)
            {
                sharedValue = 100;
                Console.WriteLine("공유 값 설정: 100");
            }
            autoEvent.Set(); // 메인에게 신호 보냄
        });

        Task.Delay(1000).ContinueWith((_) =>
        {
            Console.WriteLine("ContinueWith로 연결된 비동기 작업");
        });

        Console.WriteLine("신호 대기 중...");
        autoEvent.WaitOne(); // 작업 스레드의 신호를 기다림

        lock (locker)
        {
            Console.WriteLine($"Main에서 공유 값 확인: {sharedValue}");
        }

        Console.WriteLine("Main 종료");
    }
}

🔍 정리

기능목적특징
Task.Delay().Wait()비동기 지연을 동기적으로 대기간단하지만 UI 스레드에서는 사용 주의
ContinueWith()작업 완료 후 후속 작업 실행 (콜백 방식)비동기 흐름 제어
lock {}공유 자원 접근 시 동기화스레드 안전 보장
AutoResetEvent스레드 간의 신호 전달Set()WaitOne() 구조

You may also like

Leave a Comment

error: Content is protected !!