스레드와 태스크
스레드와 태스크
Reflection
Abstract
Thread와 Task는 비동기 프로그래밍을 위한 두 가지 주요 도구입니다. Thread는 직접 스레드를 관리하고 제어하는 방법을 제공하며, Task는 비동기 작업을 쉽게 처리할 수 있도록 도와줍니다. async와 await는 비동기 코드를 더 읽기 쉽게 만들어주며, 비동기 프로그래밍의 기본 개념을 이해하는 데 도움이 됩니다.
프로세스와 스레드
스레드 시작하기
C#에서는 System.Threading.Thread 클래스를 사용하여 새로운 스레드를 시작할 수 있습니다.
using System;
using System.Threading;
class Program
{
static void Main()
{
Thread t = new Thread(() => Console.WriteLine("새 스레드에서 실행"));
t.Start();
Console.WriteLine("메인 스레드에서 실행");
}
}스레드 임의로 종료하기
Thread.Abort()는 더 이상 권장되지 않으며, 일반적으로 스레드 내부에서 종료 조건을 체크하도록 설계합니다.
using System;
using System.Threading;
class Program
{
static void Main()
{
bool stop = false;
Thread t = new Thread(() =>
{
while (!stop)
{
Console.WriteLine("작업 중...");
Thread.Sleep(500);
}
Console.WriteLine("스레드 종료");
});
t.Start();
Thread.Sleep(2000);
stop = true;
}
}스레드의 일생과 상태 변화
스레드는 다음과 같은 상태를 가집니다: Unstarted, Running, WaitSleepJoin, Suspended, Stopped.
Thread t = new Thread(SomeMethod);
Console.WriteLine(t.ThreadState); // Unstarted
t.Start();
Console.WriteLine(t.ThreadState); // Running 또는 WaitSleepJoin인터럽트: 스레드를 임의로 종료하는 다른 방법
Thread.Interrupt()를 사용하면 Thread.Sleep이나 Wait 중인 스레드를 예외를 발생시켜 종료시킬 수 있습니다.
Thread t = new Thread(() =>
{
try
{
Thread.Sleep(5000);
}
catch (ThreadInterruptedException)
{
Console.WriteLine("인터럽트로 인해 스레드 종료");
}
});
t.Start();
Thread.Sleep(1000);
t.Interrupt();스레드 간 동기화
lock, Monitor, Mutex, Semaphore, AutoResetEvent 등의 동기화 도구를 사용할 수 있습니다.
class Counter
{
private int count = 0;
private object lockObj = new object();
public void Increment()
{
lock (lockObj)
{
count++;
}
}
}Task와 Task 그리고 Parallel
System.Threading.Tasks.Task 클래스
Task 클래스는 작업 단위를 비동기적으로 실행할 수 있도록 도와줍니다.
using System;
using System.Threading.Tasks;
class Program
{
static void Main()
{
Task t = Task.Run(() => Console.WriteLine("Task 실행 중"));
t.Wait();
}
}코드의 비동기 실행 결과를 주는 Task 클래스
Task<TResult>는 결과를 반환하는 비동기 작업을 표현합니다.
Task<int> t = Task.Run(() =>
{
return 42;
});
Console.WriteLine($"결과: {t.Result}");손쉬운 병렬 처리를 가능케 하는 Parallel 클래스
Parallel.For 및 Parallel.ForEach를 통해 반복 작업을 병렬로 처리할 수 있습니다.
Parallel.For(0, 5, i =>
{
Console.WriteLine($"인덱스 {i} 처리 중 (스레드 {Thread.CurrentThread.ManagedThreadId})");
});async 한정자와 await 연산자로 만드는 비동기 코드
async/await를 통해 비동기 흐름을 명시적으로 표현할 수 있습니다.
using System;
using System.Net.Http;
using System.Threading.Tasks;
class Program
{
static async Task Main()
{
string result = await DownloadContentAsync();
Console.WriteLine(result);
}
static async Task<string> DownloadContentAsync()
{
using (HttpClient client = new HttpClient())
{
return await client.GetStringAsync("https://example.com");
}
}
}