asyncsemaphore 不是 .net 原生类型,而是社区基于 semaphoreslim 封装的语法糖;semaphoreslim 本身已原生支持异步等待(waitasync)和取消令牌,直接使用更简可控。

没有 AsyncSemaphore 这个类型 —— 它是社区封装的“语法糖”,不是 .NET 原生类;而 SemaphoreSlim 是官方提供的、支持异步等待的轻量信号量。
为什么搜不到 AsyncSemaphore 的官方文档?
因为 AsyncSemaphore 并不存在于 System.Threading 或任何 .NET 标准库中。它是开发者(比如在 NuGet 上的 Microsoft.VisualStudio.Threading 或某些开源项目)基于 SemaphoreSlim 封装的一层薄包装,目的通常是:
- 把
WaitAsync()+using模式固化成await using友好结构 - 自动处理
Release()(比如用IDisposable或IAsyncDisposable) - 隐藏
CancellationToken传递细节
它不解决新问题,只是让常见用法更安全、不易漏 Release。
SemaphoreSlim 本身已原生支持异步:别绕路封装
.NET Framework 4.5+ 和所有 .NET Core / .NET 5+ 都自带 SemaphoreSlim.WaitAsync(),无需额外引入“AsyncSemaphore”类。直接用它就是最简、最可控的方式:
var semaphore = new SemaphoreSlim(initialCount: 3, maxCount: 3);
<p>await semaphore.WaitAsync(cancellationToken);
try
{
// 执行受保护的异步操作
await SomeIoOperationAsync();
}
finally
{
semaphore.Release();
}注意要点:
2013年07月06日 V1.60 升级包更新方式:admin文件夹改成你后台目录名,然后补丁包里的所有文件覆盖进去。1.[新增]后台引导页加入非IE浏览器提示,后台部分功能在非IE浏览器下可能没法使用2.[改进]淘客商品管理 首页 列表页 内容页 的下拉项加入颜色来区别不同项3.[改进]后台新增/修改淘客商品,增加淘宝字样的图标和天猫字样图标改成天猫logo图标4.[改进]为统一名称,“分类”改
-
WaitAsync()支持CancellationToken,能响应取消请求(Semaphore不支持) - 必须配对
Release(),否则计数泄漏 → 后续所有WaitAsync()都会永久挂起 - 不要在
catch块外释放 ——try/finally是底线,using不适用(它没实现IAsyncDisposable)
什么时候才该考虑封装一个“AsyncSemaphore”?
仅当你的项目反复出现以下模式,且团队多人容易写错时:
- 每次都要手写
try/finally+Release() - 经常忘记传
cancellationToken,导致无法取消等待 - 需要统一记录等待超时、统计并发峰值等可观测性逻辑
此时可自己写一个极简封装(20 行内),例如:
public sealed class AsyncSemaphore : IAsyncDisposable
{
private readonly SemaphoreSlim _semaphore;
<pre class='brush:php;toolbar:false;'>public AsyncSemaphore(int initialCount) => _semaphore = new SemaphoreSlim(initialCount);
public async ValueTask<IDisposable> EnterAsync(CancellationToken ct = default)
{
await _semaphore.WaitAsync(ct);
return new Releaser(_semaphore);
}
private struct Releaser : IDisposable
{
private readonly SemaphoreSlim _s;
public Releaser(SemaphoreSlim s) => _s = s;
public void Dispose() => _s.Release();
}
public async ValueTask DisposeAsync() => await Task.CompletedTask;}
但请记住:这仍是建立在 SemaphoreSlim 之上的便利层,不是替代品。
真正容易被忽略的是:无论用原生 SemaphoreSlim 还是自封的 AsyncSemaphore,都必须确保 Release() 在 *每一次* WaitAsync() 成功后被执行 —— 缺一次,整个信号量就卡死。这不是异常,也不会报错,只会让后续所有线程/任务无声地 hang 住。









