카테고리:

2 분 소요

문제 상황

.NET Core 3.1 버전까지의 C#에서는 Thread를 강제종료할 때 아래와 같이 Abort 함수를 사용한다.

static void Main(string[] args) {
    Thread thread = new Thread(foo) {
        IsBackground = true
    };

    thread.Start();
    Thread.Sleep(5000);

    thread.Abort();
}

static void foo() {
    int i = 0;
    while (true) {
        Console.WriteLine(i);
        i++;
        Thread.Sleep(1000);
    }
}

하지만, .NET 5 버전 이상의 프로젝트에서는 아래와 같은 예외가 발생하며 프로그램을 정지시킨다.

System.PlatformNotSupportedException: 'Thread abort is not supported on this platform.'

공식 문서에 따르면 아래와 같은 이유로 해당 함수의 사용을 금지시켰다고 한다.

When you call Thread.Abort to abort a thread other than the current thread, you don’t know what code has executed or failed to execute when the ThreadAbortException is thrown. You also cannot be certain of the state of your application or any application and user state that it’s responsible for preserving.

현재 스레드가 아닌 다른 스레드를 중단하기 위해 Thread.Abort를 호출하면 ThreadAbortException이 발생할 때 어떤 코드가 실행되었거나 실행되지 않았는지 알 수 없습니다. 또한 애플리케이션의 상태 또는 애플리케이션이 보존해야 하는 애플리케이션 및 사용자 상태를 확신할 수 없습니다.

https://learn.microsoft.com/en-us/dotnet/core/compatibility/core-libraries/5.0/thread-abort-obsolete

문제 해결

.NET Framework 4부터 도입된 협조적 취소를 모델인 CancellationTokenSource를 사용하여 스레드를 정지시킬 수 있다.

static void Main(string[] args) {
    CancellationTokenSource cts = new();
    Thread thread = new(() => foo(cts.Token)) {
        IsBackground = true
    };

    thread.Start();
    Thread.Sleep(5000);

    cts.Cancel();
    cts.Dispose();
}

static void foo(CancellationToken token) {
    int i = 0;
    while (true) {
        token.ThrowIfCancellationRequested();

        Console.WriteLine(i);
        i++;
        Thread.Sleep(1000);
    }
}

참고

https://learn.microsoft.com/ko-kr/dotnet/fundamentals/syslib-diagnostics/syslib0006
https://learn.microsoft.com/ko-kr/dotnet/standard/threading/cancellation-in-managed-threads

태그: .NET, abort, CancellationToken, CancellationTokenSource, PlatformNotSupportedException, syslib0006, Thread, thread.abort, ThreadAbortException, ThrowIfCancellationRequested

업데이트: