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

วิธีตรวจสอบว่า Thread เป็น Background Thread หรือไม่ใน C#

Thread.IsBackground - ตรวจสอบ Background Thread

Thread.IsBackground Property (Get/Set) ระบุว่า Thread นั้นเป็น Background Thread หรือ Foreground Thread

Background vs Foreground Thread

คุณสมบัติForeground ThreadBackground Thread
DefaultThread ใหม่ (new Thread) = ForegroundThreadPool Thread = Background
Process ExitProcess รอจบ Foreground Thread ทั้งหมดProcess จบได้ทันที Foreground จบ (Background ถูก Kill)
ใช้สำหรับMain Logic, UI, Critical WorkHelper, 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 ในการออกแบบ

ScenarioThread Typeเหตุผล
Main Application LogicForegroundต้องทำให้เสร็จ
Logging/TelemetryBackgroundไม่สำคัญถ้าหาย
File WatcherBackgroundรันตลอดกาล ไม่ Block Exit
Cache CleanupBackgroundBest Effort
SignalR/Long PollingForegroundต้องคง 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 โดยตรง