SemaphoreSlim 是 .NET 中用于并发控制的轻量级信号量类,广泛应用于限制对共享资源的并发访问,尤其在异步编程场景中

发布时间:2026/5/19 12:51:35

SemaphoreSlim 是 .NET 中用于并发控制的轻量级信号量类,广泛应用于限制对共享资源的并发访问,尤其在异步编程场景中 SemaphoreSlim 是 .NET 中用于并发控制的轻量级信号量类,广泛应用于限制对共享资源的并发访问,尤其在异步编程场景中。结合TCPSemaphore 代码(使用 SemaphoreSlim 控制 TCP 数据处理的并发),我将详细讲解 SemaphoreSlim 的工作原理,包括其内部机制、关键方法、状态管理,以及在你的代码中的具体应用。之后,我会提供示例代码和优化建议,确保其在 TCP 数据处理场景中的作用和潜在改进点。1. SemaphoreSlim 工作原理1.1 基本概念SemaphoreSlim 是一个轻量级的信号量实现,用于控制多个线程或任务对共享资源的访问。它维护一个计数器(CurrentCount),表示当前可用的“槽位”(即允许并发的任务数)。当任务需要访问资源时,它尝试获取信号量(减少计数);完成后释放信号量(增加计数)。计数器:初始计数 (initialCount):创建 SemaphoreSlim 时指定的初始可用槽位数。最大计数 (maxCount):信号量允许的最大槽位数,防止计数无限增加。当前计数 (CurrentCount):运行时表示当前可用槽位数,范围为 [0, maxCount]。作用:限制并发任务数量,保护共享资源(如你的 _dataCache 或 UI 更新)。异步支持:提供 WaitAsync 方法,适合异步编程,避免阻塞线程。1.2 内部机制SemaphoreSlim 的核心是一个计数器,结合任务协调和锁机制,具体工作原理如下:初始化:创建时指定 initialCount 和 maxCount,如 new SemaphoreSlim(2, 4):初始 CurrentCount = 2,允许 2 个任务立即进入。最大 CurrentCount = 4,限制总并发数。内部维护一个等待任务队列(TaskNode 链表),用于存储等待信号量的异步任务。获取信号量 (Wait / WaitAsync):同步 Wait:如果 CurrentCount 0,计数减 1,立即返回;否则,阻塞线程直到有可用槽位或超时。异步 WaitAsync:如果 CurrentCount 0,计数减 1,返回 Taskbool(true);否则,将任务加入等待队列,返回未完成的 Task,等待信号量释放或超时/取消。超时和取消:WaitAsync(timeout, token) 支持超时(毫秒)和 CancellationToken,超时或取消时返回 false 或抛出 OperationCanceledException。释放信号量 (Release):增加 CurrentCount(但不超过 maxCount),唤醒等待队列中的任务(按 FIFO 顺序)。如果 CurrentCount 已达 maxCount,调用 Release 会抛出 SemaphoreFullException。状态管理:CurrentCount 是核心状态,记录可用槽位。内部使用自旋锁(SpinLock)或轻量级同步机制(如 Monitor)管理计数器更新,确保线程安全。异步等待通过 TaskCompletionSource 实现,任务挂起时不占用线程。轻量级设计:相比传统的 Semaphore(基于内核信号量),SemaphoreSlim 使用用户态同步,减少上下文切换开销,适合高频操作。异步方法(WaitAsync)与 async/await 配合,适合 I/O 密集型场景。1.3 关键方法和属性构造器:csharppublic SemaphoreSlim(int initialCount, int maxCount);设置初始和最大计数。WaitAsync:csharppublic Taskbool WaitAsync(int millisecondsTimeout, CancellationToken cancellationToken);/

相关新闻