Thread (เธรด) คือเส้นทางการทำงาน (Execution Path) ของโปรแกรม แต่ละ Thread มี Flow of Control ที่เป็นเอกลักษณ์ของตัวเอง หากแอปพลิเคชันมีงานที่ซับซ้อนและใช้เวลานาน การใช้ Multiple Threads จะช่วยให้ทำงานหลายอย่างพร้อมกันได้ (Concurrency/Parallelism)
Thread Life Cycle (วัฏจักรชีวิตของ Thread)
| State | คำอธิบาย |
|---|---|
| Unstarted | สร้าง Thread object แล้วแต่ยังไม่เรียก Start() |
| Ready (Runnable) | พร้อมรัน รอ CPU Time Slice |
| Running | กำลังทำงานอยู่ |
| Not Runnable (Blocked) | รอ I/O, Sleep(), Wait(), Join(), Lock |
| Dead (Terminated) | ทำงานเสร็จ หรือถูก Abort() (Deprecated) |
สร้างและเริ่ม Thread แบบพื้นฐาน
using System;
using System.Threading;
namespace Demo {
class Program {
// เมธอดที่ Thread จะรัน
public static void ThreadFunc() {
Console.WriteLine("Child thread starts");
Thread.Sleep(1000); // จำลองงานที่ใช้เวลา
Console.WriteLine("Child thread ends");
}
static void Main(string[] args) {
Console.WriteLine("In Main: Creating the Child thread");
// สร้าง Thread ใหม่
ThreadStart childRef = new ThreadStart(ThreadFunc);
Thread childThread = new Thread(childRef);
// เริ่มการทำงาน
childThread.Start();
Console.WriteLine("Main thread continues...");
Console.ReadKey();
}
}
}
ผลลัพธ์ (ลำดับอาจสลับได้)
In Main: Creating the Child thread
Main thread continues...
Child thread starts
Child thread ends
รูปแบบการสร้าง Thread แบบต่างๆ
1. ใช้ Lambda Expression
Thread t = new Thread(() => {
Console.WriteLine("Lambda thread running");
});
t.Start();
2. ส่งพารามิเตอร์ด้วย ParameterizedThreadStart
static void Work(object data) {
Console.WriteLine("Data: " + data);
}
Thread t = new Thread(Work);
t.Start("Hello from thread");
3. ใช้ Task (แนะนำสำหรับ .NET 4.0+)
using System.Threading.Tasks;
// เรียบง่ายกว่า Thread โดยตรง
Task.Run(() => {
Console.WriteLine("Running on ThreadPool");
});
// รองรับ async/await
async Task DoWorkAsync() {
await Task.Delay(1000);
Console.WriteLine("Async done");
}
Thread Synchronization (การซิงโครไนซ์)
เมื่อหลาย Thread เข้าถึงข้อมูลร่วมกัน ต้องมีการควบคุมเพื่อป้องกัน Race Condition
lock Statement
private static readonly object _lock = new object();
private static int _counter = 0;
public static void Increment() {
lock (_lock) {
_counter++; // Thread-safe
}
}
Monitor Class
Monitor.Enter(_lock);
try {
// Critical section
} finally {
Monitor.Exit(_lock);
}
Interlocked (สำหรับ Operation แบบ Atomic)
Interlocked.Increment(ref _counter); // Atomic increment
Interlocked.CompareExchange(ref _counter, newValue, oldValue);
Thread Pool vs Manual Threads
| ด้าน | Thread (Manual) | ThreadPool / Task |
|---|---|---|
| Overhead | สูง (สร้าง OS Thread) | ต่ำ (Reuse threads) |
| Scalability | จำกัด (~1000+ threads) | สูงมาก |
| ควบคุมได้ | เต็มที่ (Priority, IsBackground) | จำกัด |
| แนะนำใช้เมื่อ | Long-running, Dedicated, ต้องการควบคุม | Short-lived, CPU-bound, I/O-bound |
Background Threads
Thread t = new Thread(Work);
t.IsBackground = true; // ไม่บล็อกโปรแกรมปิด
t.Start();
// โปรแกรมจะปิดได้แม้ Background thread ยังทำงานอยู่