Computer >> บทช่วยสอนคอมพิวเตอร์ >  >> การเขียนโปรแกรม >> C#

วิธีตรวจสอบว่า Thread ยังทำงานอยู่หรือไม่ใน C#

Thread.IsAlive - ตรวจสอบสถานะ Thread

Thread.IsAlive (Property) คืนค่า true ถ้า Thread เริ่มทำงานแล้ว (Start()) และยังไม่จบ (ยังไม่ Return จาก Method หรือ Abort)

สถานะ Thread (ThreadState)

StateคำอธิบายIsAlive
Unstartedยังไม่ Start()False
RunningกำลังทำงานTrue
WaitSleepJoinรอ (Sleep, Wait, Join)True
Suspendedถูก Suspend (Obsolete)True
Stoppedจบการทำงาน / AbortFalse
Abortedถูก AbortFalse

ตัวอย่างที่ 1: Main Thread และ ThreadPool


using System;
using System.Threading;

public class Demo
{
    public static void Main()
    {
        Thread thread = new Thread(new ThreadStart(Demo1));
        thread = Thread.CurrentThread;  // Main Thread
        
        Console.WriteLine($"Is the thread alive? = {thread.IsAlive}");  // True
        Console.WriteLine($"Current state of Thread = {thread.ThreadState}");  // Running
        Console.WriteLine($"ManagedThreadId = {thread.ManagedThreadId}");
        
        thread.IsBackground = true;
        Console.WriteLine($"Is Background Thread? = {thread.IsBackground}");  // True
        
        ThreadPool.QueueUserWorkItem(new WaitCallback(Demo2));
    }
    
    public static void Demo1()
    {
        Thread.Sleep(2000);
    }
    
    public static void Demo2(object stateInfo)
    {
        Console.WriteLine($"ThreadPool Thread? = {Thread.CurrentThread.IsThreadPoolThread}");  // True
    }
}

ผลลัพธ์:

Is the thread alive? = True
Current state of Thread = Running
ManagedThreadId = 1
Is Background Thread? = True
ThreadPool Thread? = True

ตัวอย่างที่ 2: Thread ใหม่ Start() แล้วตรวจสอบ


using System;
using System.Threading;

public class Demo
{
    public static void Main()
    {
        Thread thread = new Thread(new ThreadStart(Demo));
        thread.Start();  // เริ่ม Thread
        
        // ตรวจสอบทันทีหลัง Start()
        Console.WriteLine($"Is the Thread alive? {thread.IsAlive}");  // True (ส่วนใหญ่)
        
        // รอจบ
        thread.Join();
        Console.WriteLine($"After Join - IsAlive: {thread.IsAlive}");  // False
    }
    
    public static void Demo()
    {
        Console.WriteLine($"ThreadPool Thread? = {Thread.CurrentThread.IsThreadPoolThread}");  // False
        Thread.Sleep(100);
    }
}

ผลลัพธ์:

Is the Thread alive? True
ThreadPool Thread? = False
After Join - IsAlive: False

Property อื่นๆ ที่เกี่ยวข้อง

Propertyคำอธิบาย
IsAliveThread เริ่มทำงานแล้วและยังไม่จบ
IsBackgroundBackground Thread (ไม่ Block Process Exit)
IsThreadPoolThreadมาจาก ThreadPool หรือสร้างเอง
ManagedThreadIdID เฉพาะของ Managed Thread
ThreadStateEnum สถานะรายละเอียด (Flags)
PriorityThread Priority

Best Practices

⚠️ Race Condition Warning:
IsAlive อาจเปลี่ยนทันทีหลังเช็ค (Thread จบระหว่างเช็คและใช้ผลลัพธ์)
  • อย่าใช้ IsAlive เพื่อตัดสินใจ Critical Logic
  • ใช้ Join(), WaitHandle, Task, CancellationToken แทน

แทนที่จะใช้ IsAlive ให้ใช้:


// ❌ ไม่แนะนำ
if (thread.IsAlive) { /* do something */ }

// ✅ ดีกว่า: Join (Block จนจบ)
thread.Join(TimeSpan.FromSeconds(5));  // Timeout support

// ✅ ดีกว่า: Task + await
var task = Task.Run(() => DoWork());
await task;  // รอจบโดยไม่ Block Thread

// ✅ ดีกว่า: CancellationToken
var cts = new CancellationTokenSource();
var task = Task.Run(() => DoWork(cts.Token), cts.Token);
cts.Cancel();  // สั่งหยุด

Background Thread vs Foreground Thread

  • Foreground Thread (Default): Process ไม่จบจนกว่า Foreground Thread ทุกตัวจะจบ
  • Background Thread: Process จบได้ทันทีที่ Foreground Thread จบทั้งหมด (Background Thread จะถูก Terminate)
  • thread.IsBackground = true; ต้องตั้ง ก่อน Start()

Thread bg = new Thread(() => 
{
    Thread.Sleep(5000);
    Console.WriteLine("Background done");  // ไม่พิมพ์เพราะ Process จบก่อน
});
bg.IsBackground = true;
bg.Start();

Thread fg = new Thread(() => 
{
    Thread.Sleep(1000);
    Console.WriteLine("Foreground done");  // พิมพ์ได้
});
fg.Start();

Console.WriteLine("Main ending");  // Process จบหลัง Foreground จบ

สรุป

  • Thread.IsAlive = True ถ้า Start() แล้วและยังไม่จบ
  • Main Thread เสมอ IsAlive = True จนกว่าโปรแกรมจบ
  • ThreadPool Thread = Background Thread เสมอ
  • อย่าใช้ IsAlive สำหรับ Synchronization - ใช้ Join/Task/CancellationToken
  • Thread.State ให้รายละเอียดมากกว่า (Flags Enum)