Thread.Interrupt() 메서드Thread.Interrupt() 메서드는 실행 중인 스레드를 중단시키는 데 사용되는 메서드이다.
스레드가 대기 상태(sleep, join, wait)에 있을 때 Interrupt() 메서드를 호출하면, ThreadInterruptedException 예외가 발생하고 스레드가 깨어난다.
만약 스레드가 실행 중일 때 Interrupt() 메서드를 호출하면, 스레드는 다음 대기 상태에 진입할 때 ThreadInterruptedException 예외를 발생시킨다.
스레드 한참 실행 중인 상태(Runnig)를 피해서 대기 상태(WaitJoinSleep 상태)에 들어갔을 때 ThreadInterruptedException 예외를 발생시켜 스레드를 중지시킨다.
Interrupt() 메서드는 스레드를 강제로 종료하는 것이 아니라, 중단 신호를 보내는 것이다. 스레드는 예외를 catch하여 작업을 계속 수행할 수도 있다.Interrupt() 메서드를 호출하면 '즉시' ThreadInterruptedException 예외가 발생하고(스레드를 중단시킴), 실행 중(대기 상태 외의 상태)일 때는 스레드를 지켜보고 있다가 '다음 대기 상태'에 진입할 때 예외가 발생한다(스레드를 중단시킴).Interrupt() 메서드를 호출하기 전에 스레드가 실행 중인지 확인해야 한다. 스레드가 이미 종료된 상태에서 Interrupt() 메서드를 호출하면 ThreadStateException 예외가 발생한다.따라서 스레드를 임의로 종료하는 것은 최후의 수단으로 사용해야 하며, 가능하면 스레드가 스스로 종료되도록 하는 것이 좋다.
Interrupt() 메서드 사용 예시
using System;
using System.Threading;
class InterruptTest
{
static void Main(string[] args)
{
Thread thread = new Thread(new ThreadStart(ThreadProc));
thread.Start();
Thread.Sleep(1000); // 1초 대기
thread.Interrupt(); // 스레드 중단
Console.WriteLine("Main thread exits.");
}
static void ThreadProc()
{
try
{
Console.WriteLine("ThreadProc starts.");
Thread.Sleep(5000); // 5초 대기
Console.WriteLine("ThreadProc ends.");
}
catch (ThreadInterruptedException)
{
Console.WriteLine("ThreadInterruptedException 발생!");
}
}
}
출력 결과
ThreadProc starts.
ThreadInterruptedException 발생!
Main thread exits.
using System;
using System.Security.Permissions;
using System.Threading;
namespace InterruptingThread
{
class SideTask
{
int count;
public SideTask(int count)
{
this.count = count;
}
public void KeepAlive()
{
try
{
Console.WriteLine("Running thread isn't gonna be interrupted");
Thread.Sleep(100);
while (count > 0)
{
Console.WriteLine($"{count--} left");
Console.WriteLine("Entering into WaitJoinSleep State...");
Thread.Sleep(10);
}
Console.WriteLine("Count : 0");
}
catch (ThreadInterruptedException e)
{
Console.WriteLine(e);
}
finally
{
Console.WriteLine("Clearing resource...");
}
}
}
class MainApp
{
static void Main(string[] args)
{
SideTask task = new SideTask(100);
Thread t1 = new Thread(new ThreadStart(task.KeepAlive));
t1.IsBackground = false;
Console.WriteLine("Starting thread...");
t1.Start();
Thread.Sleep(100);
Console.WriteLine("Interrupting thread...");
t1.Interrupt();
Console.WriteLine("Wating until thread stops...");
t1.Join();
Console.WriteLine("Finished");
}
}
}
이 C# 코드는 스레드의 Interrupt() 메서드를 사용하여 스레드를 중단시키는 방법을 보여주는 예제입니다. SideTask 클래스는 KeepAlive() 메서드에서 Thread.Sleep()을 사용하여 스레드를 일시 중지하고, count 값을 감소시키면서 작업을 수행합니다. MainApp 클래스는 SideTask 객체를 생성하고 스레드를 시작한 후, Interrupt() 메서드를 사용하여 스레드를 중단시킵니다.
SideTask 클래스
int count: 작업 카운트를 저장하는 필드입니다.SideTask(int count): 생성자로, count 필드를 초기화합니다.KeepAlive(): 스레드가 실행할 메서드입니다.try 블록:while (count > 0) 루프를 실행합니다. 루프 내부에서 count 값을 감소시키고 "Entering into WaitJoinSleep State..." 메시지를 출력한 후 10밀리초 동안 스레드를 일시 중지합니다.count 값이 0이 되면 "Count : 0" 메시지를 출력합니다.catch (ThreadInterruptedException e) 블록: ThreadInterruptedException 예외가 발생하면 예외 객체 e를 출력합니다.finally 블록: "Clearing resource..." 메시지를 출력합니다.MainApp 클래스
Main 메서드:SideTask task = new SideTask(100);: SideTask 객체를 생성합니다.Thread t1 = new Thread(new ThreadStart(task.KeepAlive));: SideTask 객체의 KeepAlive() 메서드를 실행할 스레드 t1을 생성합니다.t1.IsBackground = false;: 스레드를 포그라운드 스레드로 설정합니다.t1.Interrupt() 메서드를 호출하여 스레드를 중단시킵니다.t1.Join() 메서드를 호출하여 스레드가 종료될 때까지 대기합니다.Thread.Interrupt() 메서드
Interrupt() 메서드를 호출하면, ThreadInterruptedException 예외가 발생하고 스레드가 깨어납니다.Interrupt() 메서드를 호출하면, 스레드는 다음 대기 상태에 진입할 때 ThreadInterruptedException 예외를 발생시킵니다.출력 결과
Starting thread...
Running thread isn't gonna be interrupted
Interrupting thread...
100 left
Entering into WaitJoinSleep State...
Wating until thread stops...
System.Threading.ThreadInterruptedException: Thread was interrupted from a waiting state.
at System.Threading.Thread.Sleep(Int32 millisecondsTimeout)
at InterruptingThread.SideTask.KeepAlive() in C:\Users\\MainApp.cs:line 28
Clearing resource...
Finished