You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

.NET 6 API中如何实现外部共享资源的独占锁定?

解决.NET 6 API中外部共享资源的并发竞态问题

由于你的API基于async-await异步架构,不能使用传统lock关键字(会阻塞线程池线程、破坏异步模型),需根据部署架构选择适配的异步锁方案:

单进程部署场景(单API实例)

使用SemaphoreSlim实现异步互斥锁,它支持异步等待,不会阻塞线程,适合单进程内的并发控制。

实现代码

// 全局静态锁实例,初始计数为1表示同时仅允许1个请求进入临界区
private static readonly SemaphoreSlim _sharedResourceLock = new SemaphoreSlim(1, 1);

[HttpPost]
public async Task<IActionResult> CreateResourcesAndModifyShared()
{
    // 异步等待获取锁
    await _sharedResourceLock.WaitAsync();
    try
    {
        // 临界区:修改外部共享资源 + 创建独立资源的逻辑
        await ModifyExternalSharedResourceAsync();
        await CreateIndependentResourcesAsync();
    }
    finally
    {
        // 无论是否发生异常,必须释放锁,避免死锁
        _sharedResourceLock.Release();
    }

    return Ok("操作完成");
}

关键注意事项

  • 必须用try-finally包裹临界区逻辑,确保锁始终被释放
  • 使用WaitAsync()而非Wait(),适配异步架构,避免阻塞线程池
  • 锁实例需设为静态,保证跨请求共享同一个锁对象

多进程部署场景(负载均衡/多API实例)

单进程锁无法跨实例生效,需使用分布式锁协调多个API实例的并发请求。以下以Redis RedLock为例(主流分布式锁实现):

实现步骤

  1. 安装NuGet包:RedLock.net、StackExchange.Redis
  2. 配置并使用分布式锁:
// 初始化RedLock工厂(建议注册为单例服务)
private readonly IRedLockFactory _redLockFactory;

public YourController(IRedLockFactory redLockFactory)
{
    _redLockFactory = redLockFactory;
}

[HttpPost]
public async Task<IActionResult> CreateResourcesAndModifyShared()
{
    // 尝试获取锁:锁名称(唯一标识共享资源)、等待超时、自动释放时间
    using var redLock = await _redLockFactory.CreateLockAsync(
        resource: "external-shared-resource-lock",
        expiryTime: TimeSpan.FromSeconds(15), // 锁自动释放时间,需大于临界区操作耗时
        waitTime: TimeSpan.FromSeconds(5),    // 等待获取锁的最长时间
        retryTime: TimeSpan.FromMilliseconds(500) // 重试间隔
    );

    if (!redLock.IsAcquired)
    {
        // 获取锁失败,返回繁忙状态让客户端重试
        return StatusCode(503, "资源繁忙,请稍后重试");
    }

    // 临界区逻辑
    await ModifyExternalSharedResourceAsync();
    await CreateIndependentResourcesAsync();

    return Ok("操作完成");
}

关键注意事项

  • 锁的自动释放时间必须大于临界区操作的最大耗时,避免锁提前释放导致竞态
  • 需处理获取锁失败的场景,返回合适的HTTP状态码引导客户端重试
  • 分布式锁依赖外部存储(如Redis、SQL Server),需保证存储服务的可用性

禁用方案提醒

绝对不要使用lock关键字处理异步代码中的并发,lock会阻塞线程,而async-await会释放线程上下文,可能导致锁被错误持有或死锁。

内容的提问来源于stack exchange,提问作者Sannix19

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.19 04:07:07