Thread.IsBackground - ตรวจสอบ Background Thread
Thread.IsBackground Property (Get/Set) ระบุว่า Thread นั้นเป็น Background Thread หรือ Foreground Thread
Background vs Foreground Thread
| คุณสมบัติ | Foreground Thread | Background Thread |
|---|---|---|
| Default | Thread ใหม่ (new Thread) = Foreground | ThreadPool Thread = Background |
| Process Exit | Process รอจบ Foreground Thread ทั้งหมด | Process จบได้ทันที Foreground จบ (Background ถูก Kill) |
| ใช้สำหรับ | Main Logic, UI, Critical Work | Helper, Cleanup, Monitoring, Non-critical |
ตัวอย่างที่ 1: Default State
using System;
using System.Threading;
public class Demo
{
public static void Main()
{
Thread thread = new Thread(new ThreadStart(Demo1));
ThreadPool.QueueUserWorkItem(new WaitCallback(Demo2));
Console.WriteLine($"Thread State: {thread.ThreadState}"); // Unstarted
Console.WriteLine($"ManagedThreadId: {thread.ManagedThreadId}");
Console.WriteLine($"Is Background (Before Start)? {Thread.CurrentThread.IsBackground}"); // False (Main Thread)
}
public static void Demo1() { Thread.Sleep(2000); }
public static void Demo2(object state)
{
Console.WriteLine($"ThreadPool Thread? {Thread.CurrentThread.IsThreadPoolThread}"); // True
}
}
ผลลัพธ์:
Thread State: Unstarted ManagedThreadId: 1 Is Background (Before Start)? False ThreadPool Thread? True
ตัวอย่างที่ 2: ตั้งค่า IsBackground = true
using System;
using System.Threading;
public class Demo
{
public static void Main()
{
Thread thread = new Thread(new ThreadStart(Demo1));
ThreadPool.QueueUserWorkItem(new WaitCallback(Demo2));
Console.WriteLine($"Thread State: {thread.ThreadState}"); // Unstarted
Console.WriteLine($"ManagedThreadId: {thread.ManagedThreadId}");
// ตั้งค่า Background ก่อน Start
thread.IsBackground = true;
Console.WriteLine($"Is Background (After Set)? {thread.IsBackground}"); // True
thread.Start();
Console.WriteLine("Main Thread Exiting...");
// Process จบทันที เพราะ Main (Foreground) จบ และ Background Thread ถูก Terminate
}
public static void Demo1()
{
Thread.Sleep(2000);
Console.WriteLine("Background Thread Completed"); // ไม่ได้พิมพ์
}
public static void Demo2(object state)
{
Console.WriteLine($"ThreadPool Thread? {Thread.CurrentThread.IsThreadPoolThread}"); // True
}
}
ผลลัพธ์:
Thread State: Unstarted ManagedThreadId: 4 Is Background (After Set)? True Main Thread Exiting...
การตรวจสอบใน Code
Thread t = Thread.CurrentThread;
Console.WriteLine($"IsBackground: {t.IsBackground}"); // Get
Console.WriteLine($"IsThreadPoolThread: {t.IsThreadPoolThread}"); // Read-only
// ตั้งค่า (ต้องทำก่อน Start)
Thread worker = new Thread(DoWork);
worker.IsBackground = true; // Set
worker.Start();
ThreadPool Thread เสมอเป็น Background
ThreadPool.QueueUserWorkItem(_ =>
{
Console.WriteLine($"IsBackground: {Thread.CurrentThread.IsBackground}"); // True
Console.WriteLine($"IsThreadPoolThread: {Thread.CurrentThread.IsThreadPoolThread}"); // True
});
// Task.Run ก็ใช้ ThreadPool
Task.Run(() =>
{
Console.WriteLine($"Task - IsBackground: {Thread.CurrentThread.IsBackground}"); // True
});
ใช้ IsBackground ในการออกแบบ
| Scenario | Thread Type | เหตุผล |
|---|---|---|
| Main Application Logic | Foreground | ต้องทำให้เสร็จ |
| Logging/Telemetry | Background | ไม่สำคัญถ้าหาย |
| File Watcher | Background | รันตลอดกาล ไม่ Block Exit |
| Cache Cleanup | Background | Best Effort |
| SignalR/Long Polling | Foreground | ต้องคง Connection |
ASP.NET Core / Modern .NET: ใช้ Task แทน
// แทน Thread โดยตรง ใช้ Task + CancellationToken
public class BackgroundService : BackgroundService
{
protected override async Task ExecuteAsync(CancellationToken stoppingToken)
{
while (!stoppingToken.IsCancellationRequested)
{
// Do work
await Task.Delay(TimeSpan.FromMinutes(5), stoppingToken);
}
}
}
// Register ใน DI
services.AddHostedService();
สรุป
Thread.IsBackground= Get/Set Property- Thread ใหม่ Default = Foreground (
IsBackground = false) - ThreadPool Thread เสมอ = Background (
IsBackground = true) - ตั้งค่า ก่อน Start() เท่านั้น
- Process จบเมื่อ Foreground Thread จบทั้งหมด (Background ถูก Terminate)
- Modern .NET: ใช้
BackgroundService,Task.Run,CancellationTokenแทน Thread โดยตรง