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

C# 限制平行執行緒數量的實作模式 (SemaphoreSlim / TPL Dataflow)

     編輯:關於C#

控制同時執行的執行緒數量是常見需求 (如限制並發下載、資料庫連線、API 呼叫)。早期常用 Thread + 計數器 + lock 手動實作,現代 C# 建議使用 SemaphoreSlim 或 TPL Dataflow 獲得更安全、可組合的方案。

方案一:SemaphoreSlim (輕量、同步/非同步通用)

using System;
using System.Threading;
using System.Threading.Tasks;

public class ConcurrencyLimiter
{
    private readonly SemaphoreSlim _semaphore;

    public ConcurrencyLimiter(int maxConcurrency)
    {
        _semaphore = new SemaphoreSlim(maxConcurrency, maxConcurrency);
    }

    // 同步版本
    public void Execute(Action action)
    {
        _semaphore.Wait();
        try { action(); }
        finally { _semaphore.Release(); }
    }

    // 非同步版本 (推薦)
    public async Task ExecuteAsync(Func asyncAction)
    {
        await _semaphore.WaitAsync();
        try { await asyncAction(); }
        finally { _semaphore.Release(); }
    }
}

// 使用範例
var limiter = new ConcurrencyLimiter(3); // 最多 3 個並發
var tasks = new List();
for (int i = 0; i < 10; i++)
{
    int id = i;
    tasks.Add(limiter.ExecuteAsync(async () =>
    {
        Console.WriteLine($"Task {id} 開始");
        await Task.Delay(1000); // 模擬 I/O
        Console.WriteLine($"Task {id} 完成");
    }));
}
await Task.WhenAll(tasks);

方案二:TPL Dataflow ActionBlock (高吞吐、管線化)

using System.Threading.Tasks.Dataflow;

var block = new ActionBlock(async id =>
{
    Console.WriteLine($"Task {id} 開始");
    await Task.Delay(1000);
    Console.WriteLine($"Task {id} 完成");
}, new ExecutionDataflowBlockOptions
{
    MaxDegreeOfParallelism = 3, // 限制並發數
    // BoundedCapacity = 100 // 可選:輸入緩衝區上限,防止記憶體暴增
});

for (int i = 0; i < 10; i++)
    await block.SendAsync(i); // 非同步送入,自動背壓

block.Complete();
await block.Completion;

方案三:Parallel.ForEach + MaxDegreeOfParallelism (CPU 密集型)

Parallel.ForEach(items, new ParallelOptions { MaxDegreeOfParallelism = 4 }, item =>
{
    // CPU 密集運算
    ProcessItem(item);
});

比較與選擇建議

場景推薦方案理由
一般非同步 I/O 限流 (HTTP、DB、檔案)SemaphoreSlim輕量、支援同步/非同步、容易嵌入既有程式碼
高吞吐管線、需背壓控制、批次處理TPL Dataflow內建緩衝區、支援連結多個 Block 形成管線、自動背壓
CPU 密集平行運算Parallel.ForEach自動分割工作、工作盜演算法、適合計算密集
需動態調整並發數SemaphoreSlim可運行時釋放/等待調整,Dataflow 需重建 Block

常見錯誤避坑

  • 忘記 Release:一定要在 finally 區塊釋放,否則信號量會洩漏導致永久阻塞。
  • 同步等待非同步:_semaphore.Wait() 會阻塞執行緒,UI/ASP.NET 應用請改用 await _semaphore.WaitAsync()。
  • 過度限制:並發數設太低會降低吞吐量;建議從 Environment.ProcessorCount * 2 (I/O) 或 ProcessorCount (CPU) 開始調整。
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved