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

C# 多線程程式設計實戰:建立、控制、資料傳遞與同步機制全解析

     編輯:關於C語言

基本線程建立與啟動

.NET 使用 System.Threading.Thread 類別管理線程。建立線程需傳入 ThreadStart 委派(無參數、無回傳值方法):


Thread t1, t2;

private void Form_Load(object sender, EventArgs e) {
    t1 = new Thread(new ThreadStart(BackgroundProcess));
    t1.Start();
}

private void BackgroundProcess() {
    int i = 1;
    while (true) {
        // UI 更新需跨線程 Marshal(見下文)
        listBox1.Items.Add($"Iterations: {i++}");
        Thread.Sleep(2000);
    }
}

線程狀態控制

Sleep(Timeout.Infinite)Suspend()Resume()Abort()Join(ms)
方法用途備註
Sleep(ms)暫停指定毫秒立即進入等待
無限期暫停需 Interrupt() 喚醒
掛起線程已過時,非安全點不會立即掛起
恢復掛起配合 Suspend 使用
強制終止拋出 ThreadAbortException,需 catch 處理
等待線程結束回傳 bool 表示是否在時間內結束

// 停止線程範例
private void btnStop_Click(object sender, EventArgs e) {
    t1.Abort(); // 簡單粗暴,生產環境建議用取消權杖
}

跨線程傳遞資料:封裝類別 + 事件模式

線程方法無參數、無回傳,解決方案:將參數與結果封裝於類別欄位,完成時觸發事件通知主線程。


public delegate void CalcCompletedEventHandler(double result);

public class SquareCalculator {
    public double Value { get; set; }
    public double Result { get; private set; }
    public event CalcCompletedEventHandler Completed;

    public void CalcSquare() {
        Result = Value * Value;
        Completed?.Invoke(Result); // 在工作線程觸發
    }
}

// 使用
private void btnCalc_Click(object sender, EventArgs e) {
    var calc = new SquareCalculator { Value = 30 };
    calc.Completed += (result) => {
        // 注意:此處仍在工作線程,更新 UI 需 Invoke
        this.Invoke(new Action(() => MessageBox.Show($"平方: {result}")));
    };
    Thread t = new Thread(calc.CalcSquare);
    t.Start();
}

線程同步機制

1. lock / Monitor


public void CalcSquareSync() {
    lock (typeof(SquareCalculator)) { // 鎖定型別物件
        Result = Value * Value;
    }
}

確保同一時間僅有一線程進入關鍵區段。

2. Thread.Join 等待完成


t2 = new Thread(calc.CalcSquare);
t2.Start();
if (t2.Join(500)) { // 等待最多 500ms
    MessageBox.Show(calc.Result.ToString());
} else {
    MessageBox.Show("計算逾時");
}

3. 現代替代方案:Task / async-await / CancellationToken

.NET 4.5+ 建議使用 Task.Run、async/await、CancellationToken 取代手動 Thread 管理,程式碼更簡潔、例外處理更完善、支援進度回報與組合。


// 現代寫法範例
private async void btnModern_Click(object sender, EventArgs e) {
    var cts = new CancellationTokenSource();
    try {
        double result = await Task.Run(() => CalcSquareAsync(30, cts.Token), cts.Token);
        MessageBox.Show($"結果: {result}");
    } catch (OperationCanceledException) {
        MessageBox.Show("已取消");
    }
}

private double CalcSquareAsync(double v, CancellationToken ct) {
    ct.ThrowIfCancellationRequested();
    Thread.Sleep(1000); // 模擬耗時運算
    return v * v;
}

UI 線程安全更新

Windows Forms / WPF 僅允許 UI 線程存取控制項。跨線程更新必須透過 Control.Invoke / Dispatcher.Invoke:


listBox1.Invoke(new Action(() => listBox1.Items.Add("新項目")));

總結

掌握 Thread 基礎操作有助於理解底層機制,但實務開發請優先採用 Task 平行程式庫 (TPL)、async/await、CancellationToken 等現代模式,配合 Concurrent 集合與 SemaphoreSlim 等同步原語,打造高效、可維護的多線程應用。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved