如何在aspcore中一次处理方法一个请求的一部分

时间:2019-02-26 13:35:38

标签: c# .net asp.net-core concurrency

我必须在数据库中增加一列,该增加可以依赖于其他列,例如由用户增加,我使用jmeter在同一时间发送多个请求,我试图使用锁但工作不正常,如何我冻结了一部分方法?

public override DepositoProduto Save(DepositoProduto entity)
    {
        lock (entity)
        {
            using (var transaction = Session.BeginTransaction())
            {
                //here auto increment
                entity.Codigo = All().OrderByDescending(x => x.Codigo).Select(x => x.Codigo).First() + 1;

                //here commit to the database
                transaction.Commit();
            }
        }
        return entity;
    }

1 个答案:

答案 0 :(得分:0)

您需要在单例作用域或静态对象上使用SemaphoreSlim。那可以是您的存储库,也可以是任何存储库,或者,如果需要将其保留在请求范围内,则可以利用备用帮助程序类来简单地处理此递增过程。信号量非常容易使用。您基本上只需要设置一个静态ivar,类型为SemaphoreSlim

private static SemaphoreSlim _semaphore = new SemaphoreSlim(1);

在这里,1指定一次只能输入一件事,这是您在特定情况下想要的。您可以在不同情况下在此处使用其他数字来基本限制速率。然后,包装运行所需的代码:

_semaphore.Wait(); // or await _semaphore.WaitAsync()

// code protected by semaphore here

_semaphore.Release();

该信号量有一个计数器。调用Wait时,信号量会将计数器加1,然后如果没有其他等待,它将返回并允许后续代码进行处理。如果计数器已经高于最大值(此处为1),那么它将不会返回,直到计数器减小到最大值以下。递减通过Release发生,在代码完成后调用。从本质上讲,这会创建一种队列,其他线程将等待机会运行受信号量保护的代码。这样一来,您可以确保一次只有一个Save呼叫正在执行任何操作,因此,增量事务将始终有效。

这与锁定类似,尤其是计数为1时,但信号量是线程安全的,而锁则不是。如果其他东西已经具有锁,那么您将简单地尝试创建该锁,并通过实现等待和重试模式,断路器等来手动恢复。信号量通过不绑定到任何特定的线程。