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

C# เทียบเท่า Java Thread.setDaemon - Background Thread

Java ใช้ Thread.setDaemon(true) ทำให้ Thread เป็น Daemon Thread (จบเมื่อ Main Thread จบ) ใน C# ใช้ Concept ของ Foreground vs Background Thread

หลักการ C#

  • Foreground Thread: Process จะไม่จบจนกว่า Foreground Thread ทั้งหมดจะจบ (Default)
  • Background Thread: Process จบได้ทันทีที่ Foreground Thread จบหมด Background Thread จะถูก Terminate ทันที

ตัวอย่าง: สร้าง Background Thread

using System;
using System.Threading;

public class Program
{
    public static void Main()
    {
        // Foreground Thread (Default)
        Thread fgThread = new Thread(ForegroundWork);
        fgThread.Name = "Foreground";
        fgThread.Start();

        // Background Thread
        Thread bgThread = new Thread(BackgroundWork);
        bgThread.Name = "Background";
        bgThread.IsBackground = true;  // Key Property!
        bgThread.Start();

        Console.WriteLine("Main thread ending...");
        // โปรแกรมจะจบทันที ไม่รอ Background Thread
    }

    static void ForegroundWork()
    {
        Thread.Sleep(2000);
        Console.WriteLine("Foreground work completed");
    }

    static void BackgroundWork()
    {
        Thread.Sleep(5000);
        Console.WriteLine("Background work completed"); // จะไม่พิมพ์เพราะ Process จบก่อน
    }
}

ผลลัพธ์

Main thread ending...
Foreground work completed
// Background work completed - จะไม่แสดง เพราะ Process Terminated แล้ว

ThreadPool Threads เป็น Background เสมอ

// Task.Run, ThreadPool.QueueUserWorkItem - ทั้งหมดเป็น Background Thread
Task.Run(() => { /* Background */ });
ThreadPool.QueueUserWorkItem(_ => { /* Background */ });

// async/await - Continuation รันบน ThreadPool (Background)
await Task.Delay(1000); // Resumes on Background Thread

ตรวจสอบ Thread Type

Thread.CurrentThread.IsBackground // true/false

// เปลี่ยนระหว่างรันได้ (ก่อน Start เท่านั้น)
Thread t = new Thread(Work);
t.IsBackground = true;  // ต้องตั้งก่อน Start()
t.Start();

// หลัง Start แล้วเปลี่ยนได้แต่ไม่แนะนำ
// t.IsBackground = false; // Valid แต่ risky

เมื่อไหร่ควรใช้ Background Thread

  • Work ที่ไม่สำคัญถ้าหยุดกลางคัน (Logging, Metrics, Cache Cleanup)
  • Fire-and-forget Operations
  • Periodic Timer Callbacks
  • Worker ที่ Main App ไม่ต้องรอ

เมื่อไหร่ต้องใช้ Foreground Thread

  • Critical Work ที่ต้องเสร็จสิ้น (Save Data, Transaction Commit)
  • Graceful Shutdown Logic
  • Background Thread ที่ต้อง Complete ก่อน Process Exit

Graceful Shutdown Pattern

public class GracefulService
{
    private readonly CancellationTokenSource _cts = new();
    private readonly Thread _worker;

    public GracefulService()
    {
        _worker = new Thread(DoWork) { IsBackground = false }; // Foreground!
        _worker.Start();
    }

    public void Stop()
    {
        _cts.Cancel();
        _worker.Join(TimeSpan.FromSeconds(5)); // รอจบสูงสุด 5 วิ
    }

    private void DoWork()
    {
        while (!_cts.Token.IsCancellationRequested)
        {
            // Work...
            Thread.Sleep(1000);
        }
        // Cleanup...
    }
}