Computer >> Hướng Dẫn Máy Tính >  >> Lập Trình >> C#

Lấy Thread ID từ Thread trong C#

Mỗi thread trong .NET có một Managed Thread ID duy nhất (integer) do CLR gán. Dùng Thread.CurrentThread.ManagedThreadId để lấy ID của thread đang chạy.

Ví dụ cơ bản


using System;
using System.Threading;

class Program
{
    static void Main()
    {
        Thread mainThread = Thread.CurrentThread;
        mainThread.Name = "Main Thread";
        
        Console.WriteLine($"Thread Name: {Thread.CurrentThread.Name}");
        Console.WriteLine($"Managed Thread ID: {Thread.CurrentThread.ManagedThreadId}");
        // Output: Managed Thread ID: 1 (thường là 1 cho main thread)
        
        // Tạo thread mới
        Thread worker = new Thread(DoWork);
        worker.Name = "Worker Thread";
        worker.Start();
        
        Console.ReadLine();
    }
    
    static void DoWork()
    {
        Console.WriteLine($"Worker - Name: {Thread.CurrentThread.Name}");
        Console.WriteLine($"Worker - Managed Thread ID: {Thread.CurrentThread.ManagedThreadId}");
        // Output: Worker - Managed Thread ID: 3, 4, 5... (tùy ThreadPool)
    }
}

Thread ID vs OS Thread ID

  • ManagedThreadId: ID do CLR quản lý, duy nhất trong process .NET, bắt đầu từ 1.
  • OS Thread ID: ID do OS cấp (GetCurrentThreadId Windows, pthread_self Linux). Khác ManagedThreadId.
  • Lấy OS Thread ID: System.Diagnostics.Process.GetCurrentProcess().Threads hoặc P/Invoke GetCurrentThreadId().

Task vs Thread


// Task chạy trên ThreadPool thread
Task.Run(() => 
{
    Console.WriteLine($"Task - Thread ID: {Thread.CurrentThread.ManagedThreadId}");
    // Thread ID có thể khác nhau mỗi lần chạy (ThreadPool reuse)
}).Wait();

// LongRunning Task -> có thể tạo thread mới
Task.Factory.StartNew(() => 
{
    Console.WriteLine($"LongRunning - Thread ID: {Thread.CurrentThread.ManagedThreadId}");
}, TaskCreationOptions.LongRunning);

Async/Await và Thread ID


static async Task Main()
{
    Console.WriteLine($"Start - Thread: {Thread.CurrentThread.ManagedThreadId}");
    
    await Task.Delay(100);
    Console.WriteLine($"After await - Thread: {Thread.CurrentThread.ManagedThreadId}");
    // Có thể KHÁC thread nếu không có SynchronizationContext (Console App)
    // Cùng thread nếu có SyncContext (UI: WPF, WinForms, ASP.NET Core request)
}

Ứng dụng thực tế

  • Debugging: Log Thread ID để trace concurrency issues.
  • Thread-local storage: ThreadLocal<T> keyed by Thread ID.
  • Performance profiling: Xem thread contention.
  • Đảm bảo code chạy trên UI thread (WPF/WinForms): Dispatcher.Invoke / Control.Invoke.

Lưu ý

  • Managed Thread ID có thể bị tái sử dụng (recycled) sau khi thread kết thúc.
  • Không dùng Thread ID làm unique key lâu dài (dùng Thread.CurrentThread.ManagedThreadId chỉ cho debug/logging tức thời).
  • Trong ASP.NET Core, không nên phụ thuộc vào Thread ID (thread pool, async context switching).