首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> .NET 網頁程式設計 >> C# >> 關於C#

C# 多執行緒入門:行程與執行緒核心概念、Thread 類別基礎操作完整教學

     編輯:關於C#

前言

多執行緒是現代軟體開發的核心技術之一,能顯著提升應用程式的回應性、吞吐量與資源利用率。在 C# 中,System.Threading 命名空間提供了完整的多執行緒支援。本文從**行程與執行緒的基本定義**出發,詳細解釋多執行緒的優缺點、Thread 類別的核心屬性與方法、主執行緒概念、靜態屬性 CurrentThread、以及建立第一個執行緒的完整步驟,為後續深入學習同步、執行緒池、非同步程式設計打下堅實基礎。

核心概念:行程 vs 執行緒

概念行程執行緒
定義執行中的程式實例,擁有獨立的虛擬記憶體空間、系統資源 (檔案控制代碼、Socket 等)行程內的**執行流**,單一行程可包含多個執行緒
資源擁有權擁有完整資源 (記憶體、代碼段、資料段、堆疊、檔案控制代碼)**共享**行程的代碼段、資料段、堆疊、檔案控制代碼;**擁有獨立**的暫存器組 (程式計數器、堆疊指標)、區域變數堆疊、TLS (執行緒區域儲存)
切換開銷大 (需切換完整記憶體上下文、MMU、快取)小 (僅切換暫存器、堆疊指標、TLS)
通訊方式IPC (管道、共享記憶體、Socket、訊息佇列)直接讀寫共享記憶體 (全域變數、靜態欄位、堆積物件)
建立/銷毀重 (核心物件、資源配置)輕 (核心執行緒物件、堆疊配置)

多執行緒的優缺點

優點

  • 提升 CPU 利用率:單核心透過時間分片「並行」;多核心透過真實平行執行。
  • 改善回應性:UI 執行緒保持流暢,耗時工作放入背景執行緒。
  • 資源共享高效:執行緒間直接存取共享記憶體,無序列化/反序列化開銷。
  • 模組化設計:將獨立邏輯封裝於獨立執行緒 (如監聽、定時器、快取清理)。

缺點與挑戰

  • 記憶體開銷:每個執行緒預設配置 1MB 堆疊 (可調整),大量執行緒耗盡記憶體。
  • 同步複雜度:共享資料需加鎖,易發生**死結**、**競爭條件**、**活結**。
  • 除錯困難:非確定性執行順序,Bug 難以重現。
  • 上下文切換成本:過多執行緒導致 CPU 花費過多時間在切換而非實際運算。
  • 例外處理:背景執行緒未捕獲例外會終止整個行程 (.NET 2.0+)。

Thread 類別核心成員

關鍵靜態屬性與方法

關鍵實例屬性與方法

成員類型說明
CurrentThread靜態屬性取得**目前正在執行程式碼的執行緒**參考 (Thread 物件)
Sleep(ms)靜態方法讓**目前執行緒**暫停指定毫秒數,釋放 CPU 時間片
GetDomain()靜態方法取得目前執行緒所屬的 AppDomain

主執行緒

  • 每個 .NET 應用程式啟動時,CLR 自動建立**主執行緒** 執行 Main 方法。
  • 主執行緒為**前景執行緒** (IsBackground = false)。
  • **所有前景執行緒結束** → 程式結束 → CLR 強制終止所有背景執行緒 (不執行 finally、不呼叫 Finalize)。
  • 主執行緒可透過 Thread.CurrentThread 存取自身。

建立第一個執行緒:完整步驟

  1. 引用命名空間:using System.Threading;
  2. 定義執行緒入口方法 (符合 ThreadStart 或 ParameterizedThreadStart 簽名)。
  3. 實例化 Thread 物件,傳入入口方法委派。
  4. (可選) 設定 Name、IsBackground、Priority。
  5. 呼叫 Start() 啟動。
  6. (可選) 主執行緒呼叫 Join() 等待結束。

最簡範例

using System;
using System.Threading;

namespace FirstThreadDemo
{
    class Program
    {
        static void Main()
        {
            // 1. 取得主執行緒並命名
            Thread mainThread = Thread.CurrentThread;
            mainThread.Name = "MainThread";
            Console.WriteLine($"[{mainThread.Name}] 啟動, ID={mainThread.ManagedThreadId}, 狀態={mainThread.ThreadState}");

            // 2. 建立子執行緒
            Thread worker = new Thread(WorkerMethod) 
            { 
                Name = "WorkerThread",
                IsBackground = false // 前景執行緒
            };

            // 3. 啟動
            worker.Start();

            // 4. 主執行緒等待子執行緒結束
            worker.Join();

            Console.WriteLine($"[{mainThread.Name}] 子執行緒已結束,程式結束。");
            Console.ReadKey();
        }

        static void WorkerMethod()
        {
            Console.WriteLine($"[{Thread.CurrentThread.Name}] 開始工作, ID={Thread.CurrentThread.ManagedThreadId}");
            for (int i = 0; i < 3; i++)
            {
                Console.WriteLine($"[{Thread.CurrentThread.Name}] 迴圈 {i}");
                Thread.Sleep(500); // 讓出 CPU
            }
            Console.WriteLine($"[{Thread.CurrentThread.Name}] 工作完成");
        }
    }
}

執行緒命名空間與組態

  • 所有多執行緒核心類別位於 System.Threading 命名空間。
  • .NET Framework 專案預設已參考 mscorlib.dll,無需額外加入參考。
  • .NET Core / .NET 5+ 專案內建於 System.Threading.Thread NuGet 套件 (隱含參考)。

常見誤區與最佳實踐

成員類型說明
Start()方法啟動執行緒,開始執行委派指向的方法
Abort()方法已淘汰:強制終止執行緒 (擲出 ThreadAbortException)
Suspend()/Resume()方法已淘汰:暫停/恢復執行緒 (極易死結)
Join()方法阻塞呼叫執行緒,直到目標執行緒結束
Interrupt()方法中斷處於 WaitSleepJoin 狀態的執行緒
Name屬性設定/取得執行緒名稱 (除錯時顯示於 Visual Studio 執行緒視窗)
IsAlive屬性執行緒是否已啟動且尚未結束
IsBackground屬性是否為背景執行緒 (不阻止程式結束)
Priority屬性執行緒優先級
ThreadState屬性執行緒狀態旗標組合
ManagedThreadId屬性執行緒唯一識別碼 (進程內唯一)

總結

行程是資源邊界,執行緒是排程單位。C# 透過 System.Threading.Thread 提供底層執行緒控制:CurrentThread 取得當前執行緒、Start 啟動、Join 等待、Sleep 讓步、Name/IsBackground/Priority 設定屬性。理解**主執行緒決定程式存活**、ThreadState 狀態機、**已淘汰 API (Abort/Suspend/Resume) 禁用**、CancellationToken 協同取消模式,是編寫健壯多執行緒程式的基石。下一階段將學習:lock/Monitor 同步、生產者-消費者模式、ThreadPool 執行緒池、Timer 定時器、Mutex 跨行程同步、現代 Task/async/await 非同步程式設計模式。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved
誤區正確做法
使用 Thread.Abort() 強制結束使用 CancellationToken 協同取消模式
使用 Thread.Suspend/Resume使用 Monitor.Wait/Pulse、AutoResetEvent、SemaphoreSlim 同步
大量建立 Thread (每請求一條)使用 ThreadPool / Task.Run / async/await 池化重用
共享資料不加鎖使用 lock、Interlocked、Concurrent 集合、Immutable 集合
在 lock 內呼叫外部方法/耗時 I/O鎖定範圍最小化,僅保護記憶體存取
忽略背景執行緒例外在執行緒入口方法最外層 try-catch 記錄例外