概念

在 C# 中,SemaphoreSlim​ 是 System.Threading​ 命名空间下的轻量级同步原语,用于限制同时访问共享资源的线程数量。

核心特性

  1. 轻量高效
    专为高性能设计,适用于进程内同步,比 Semaphore​ 类更高效。

  2. 异步支持
    提供 WaitAsync()​ 方法,支持异步编程模型,避免线程阻塞。

  3. 并发控制
    通过计数器限制资源访问线程数,初始计数(initialCount​)表示可用资源数,最大计数(maxCount​)为资源上限。

构造函数

SemaphoreSlim(int initialCount);  // 初始计数,最大计数默认为 int.MaxValue
SemaphoreSlim(int initialCount, int maxCount);  // 指定初始和最大计数
  • 说明:initialCount​ 必须 ≥0 且 ≤ maxCount​,否则抛出 ArgumentOutOfRangeException​。

常用方法

方法

说明

​Wait()​

同步等待信号量,计数器减1;若计数为0则阻塞。

WaitAsync()​

异步等待信号量,适用于非阻塞异步场景。

​Release()​

释放信号量,计数器加1(默认释放1次,可指定次数 Release(n)​)。

Dispose()​

释放资源,避免内存泄漏。

使用场景

  1. 资源池管理
    如数据库连接池、文件句柄池等,限制并发访问数量。

  2. 异步任务协调
    控制异步任务并发度,避免资源过载。

  3. 生产者-消费者模型
    同步生产者和消费者的资源访问节奏。

代码示例

示例1:同步控制(限制3个线程)

static SemaphoreSlim semaphore = new SemaphoreSlim(3);

static void AccessResource(string name, int seconds)
{
    semaphore.Wait();
    try
    {
        Console.WriteLine($"{name} 访问资源");
        Thread.Sleep(seconds * 1000);
    }
    finally
    {
        semaphore.Release();
    }
}

示例2:异步控制(异步等待)

static SemaphoreSlim semaphore = new SemaphoreSlim(1,1);

static async Task AccessResourceAsync(string name, int seconds)
{
    await semaphore.WaitAsync();
    try
    {
        Console.WriteLine($"{name} 开始异步操作");
        await Task.Delay(seconds * 1000);
    }
    finally
    {
        semaphore.Release();
    }
}

注意事项

  • 初始计数为0:需手动调用Release(n)​初始化资源池,否则所有线程会被阻塞。

  • 线程安全Dispose()​方法非线程安全,需确保释放时无其他操作。

  • 与Semaphore区别Semaphore​支持跨进程和命名信号量,而SemaphoreSlim​仅限进程内使用但性能更优。