C# 多執行緒程(Multithreading)【一】

多執行緒的主要作用

1. 提升效能(Performance)

  • 可同時執行多個工作,讓 CPU 利用率提高。
  • 避免單一工作阻塞整個應用程式。

2. 改善回應性(Responsiveness)

  • UI 程式中,如果長時間任務(例如:下載、運算)不使用背景執行緒,介面會「卡住」或無回應(Not Responding)
  • 使用背景執行緒可以保持介面流暢。

3. 支援背景任務

  • 比如記錄檔寫入、資料同步、訊息處理等,可以在不打擾主流程的情況下在背景執行。

注意事項

  • 多執行緒會有 資源同步 問題(如兩個執行緒同時寫入同一變數),需要使用 lock 或其他同步機制。
  • 不當使用可能導致 死結(Deadlock) 或 Race condition。
  • 執行緒過多反而會降低效能(執行緒切換成本高)。


實行 多執行緒(Multithreading)的幾種方法

方法 是否推薦 特點
Thread 基礎、控制度高但效率差
ThreadPool ⚠️ 簡單但不適合複雜任務追蹤
Task / async-await ✅✅✅ 現代標準,清晰高效
Parallel 適合資料密集工作
BackgroundWorker 舊式,不建議
Reactive Extensions / Dataflow ⚙️ 進階場景、資料流模型

1. 使用 Thread 類別(基礎做法)

這是最原始的多執行緒方式,直接建立和啟動執行緒。

Thread t = new Thread(new ThreadStart(MethodName));
t.Start();

✅ 優點:控制度高

❌ 缺點:資源耗費高、不易管理、無法回傳結果


2. 使用 ThreadPool(執行緒池)

用來重複使用系統內的執行緒,減少建立成本。

ThreadPool.QueueUserWorkItem(state => {
// 背景工作
});

✅ 較省資源

❌ 難以追蹤完成情況、無回傳值


3. 使用 Task / async-await(現代推薦用法)

是目前主流,較簡潔、支援回傳結果、整合 async/await。

Task.Run(() => {
// 執行非同步工作
});

或有回傳值:

Task task = Task.Run(() => {
return 42;
});
int result = task.Result; // 或 await task;

4. 使用 async / await(非同步程式設計)

這不直接建立執行緒,而是以非同步方式讓系統分配工作。

async Task MyMethodAsync() {
await Task.Delay(1000); // 非同步等待,不阻塞執行緒
}

✅ 高可讀性、整合 Task

❌ 需注意執行緒同步與例外處理


5. 使用 Parallel 類別(資料平行化)

可並行執行迴圈、方法,適合處理 CPU-bound 工作。

Parallel.For(0, 10, i => {
Console.WriteLine(i);
});

✅ 快速、適合大量資料處理

❌ 控制度較低、不適合 I/O-bound 工作


其他補充元件(與多執行緒配合使用):

元件 用途與描述
lock / Monitor 保護共用資源,避免競爭條件(race condition),適合臨界區控制。
Semaphore / Mutex 控制同時執行的執行緒數量,或用於跨程序資源同步。
CancellationToken 提供中止 `Task`、`Parallel` 等非同步作業的能力,支援取消流程。
ConcurrentQueue 執行緒安全的集合類別,適合在多執行緒環境中安全地共享資料。

留言

2025

05-27C# 多執行緒程(Multithreading)【五】task
05-21C# 多執行緒程(Multithreading)【四】ThreadPool
05-19C# 多執行緒程(Multithreading)【三】UI操作
05-19C# 多執行緒程(Multithreading)【二】Thread
05-12C# 多執行緒程(Multithreading)【一】
05-05WMI (Windows管理規範)與WQL(WMI 查詢語言)
04-30WndProc 視窗處理函數【三】USB裝置插入/移除偵測
04-29WndProc 視窗處理函數【二】Windows Messages (WM_*) 分類清單
04-29WndProc 視窗處理函數【一】

2024

11-27SPI Flash 操作 (Read/Write/Erase)
11-19Rotary Encoder Switch 旋轉編碼開關
11-14Command Line Interface - CLI via UART
11-14【STM32】USB HID - Volume Control
11-13【STM32】USB Custom HID
11-12【STM32】USB HID Keyboard + Mouse
11-12【STM32】USB HID Keyboard
11-12【STM32】USB HID Mouse
10-15SSD1306 128x64 OLED 【五】Wokwi Animator
09-2432F429IDISCOVERY - - LTDC [3] + FMC (SDRAM) + FatFS
09-2432F429IDISCOVERY - - LTDC [2] + FMC (SDRAM)
09-20STM32 + FatFs + SD card via SPI【三】FatFS指令操作II
09-19STM32 + FatFs + SD card via SPI【二】FatFS指令操作
09-18STM32 + FatFs + SD card via SPI【一】移植FatFS
09-0232F429IDISCOVERY - - LTDC [1]
04-17SSD1306 128x64 OLED 【四】Adafruit / GFX Library
04-17Arduino - Serial Plotter繪圖儀
04-16SSD1306 128x64 OLED 【三】
04-15SSD1306 128x64 OLED 【二】 Datasheet
04-12SSD1306 128x64 OLED 【一】I2C版本
03-20【freeRTOS】vTaskDelay 與 vTaskDelayUntil 的差異
03-19【freeRTOS】API功能列表
03-18【freeRTOS】Day1
03-08MBR和Blank project的差別
03-05刪除註冊檔registry的資料
02-27DFU over Bluetooth Low Energy
02-27nRF Util - 使用手冊
02-26nRF Command Line Tools
02-20建立BootLoader settings
02-19Secure DFU packet (ZIP) build 建立含袐鑰的Zip檔
02-19Secure DFU via BLE
02-19Secure DFU via UART
02-16nRF Util 安裝
01-16nRF52840 ic升級成nRF52840 Dongle的程式

2023

11-21[ SEGGER Embedded Studio ] 新增header files
11-21[ SEGGER Embedded Studio ] 編譯nRF52840時遇到的問題
11-07Arduino Nano ESP32 - Debugging除錯模式
11-03Git快速入手 - 使用Git GUI
10-30Git快速入手 - 使用Git Bash
10-12程式碼高亮顯示 -- google-code-prettify

2022

11-30[EZ-PD] CCG6DF CCG6SF的Host SDK遇到編譯錯誤(一)

2019

05-27[ Eagle PCB ] 合板成品
05-23#CASE_001_USB_TOOL_RL78_G12
05-22[ Eagle PCB ] 初次洗板
05-21[ Eagle PCB ] Panelize 併板
05-20[ Eagle PCB ] 建立自己的Library及元件
05-20[ Eagle PCB ] 添加library及元件
05-20[ Eagle PCB ] Introduce

2018

04-25[ TCP test Tool ] 好用的TCP Server/Client工具
01-16RZ/A1H -[0]- Renesas RZ/A1H YR0K77210S009BE BSP環境架設

2017

12-11EZ USB Suit使用JLink online debug FX3
10-20RL78 -[12]- CS+_CACX_Lab5_LowPower mode
10-16RL78 -[11]- CS+_CACX_Lab4_ADC_溫度感測
10-13RL78 -[10]- CS+_CACX_Lab4_ADC_內部參考電壓
10-13RL78 -[9]- CS+_Lab3_I2C + MPU6050
10-13RL78 -[8]- CS+_Lab2_Uart transmit
10-12RL78 -[7]- Renesas Flash Programmer 獨立燒錄軟體
10-12RL78 -[6]- CS+_雜記
10-12RL78 -[5]- CS+_tracking variables on debug mode
10-12RL78 -[4]- CS+_顯示ROM與RAM的使用size
10-12RL78 -[3]- CS+_Lab1_Led blinking
10-12RL78 -[2]- CS+專案建立
10-12RL78 -[1]- 開發環境介紹
10-06ESP-01 -[0]- 硬體設置
10-06LinkIt 7688 program Renesas RL78/G12 by 1-wire
10-06LinkIt Smart 7688 -[3]- Build the firmware from source codes
10-06LinkIt Smart 7688 -[2]- 使用UART進入bootloader / kernel console
10-06LinkIt Smart 7688 -[1]- 使用SSH連接kernel console
10-06LinkIt Smart 7688 -[0]- 初次使用
07-14LinkIt Smart 7688 -[9]- Using MRAA SPI in Python
07-13LinkIt Smart 7688 -[8]- Using MRAA UART in Python
07-12LinkIt Smart 7688 -[7]- Using MRAA I2C in Python
07-12LinkIt Smart 7688 -[6]- Using MRAA PWM in Python
07-12LinkIt Smart 7688 -[5]- Using MRAA GPIO in Python
07-10LinkIt Smart 7688 -[4]- 雜記
06-29輕乳酪蛋糕 Cotton Cheesecake
06-26VirtualBox 的 Ubuntu與Windows 共用資料夾

2015

04-29偵測USB PnP