如何在网络核心3中的任务之间同步方法调用

问题描述 投票:0回答:1

在我的应用程序中,我有一个BackgroundService,它还包含以下方法:

  • GetNumberAsync()从数据库中获取“最旧的”记录,并更新记录的属性。

此方法从API控制器异步方法调用,例如:

[HttpGet]
[Route("GetNumber")]
public async Task<ActionResult<string>> GetNumber()
{
    return Ok(await _numberService.GetNumberAsync());
}

恐怕如果同时发生两个或多个GetNumberAsync()调用,那么其中一些可能会获得相同的记录。如何避免这种情况,因为每个调用都应返回唯一记录?

方法代码:

    internal async Task<string> GetNumberAsync()
    {
        var num = await _smsDbContext.ZadarmaPhoneNumbers
            .OrderBy(x => x.LockedTime)
            .FirstOrDefaultAsync();

        if(num != null)
        {
            num.LockedTime = DateTime.Now;
            num.SmsCode = "";

            _smsDbContext.ZadarmaPhoneNumbers.Update(num);

            await _smsDbContext.SaveChangesAsync();

            return num.Number;
        }

        return "";
    }

谢谢。

c# asp.net-core async-await entity-framework-core thread-synchronization
1个回答
0
投票

这里是如何实现它的想法。

假设您有这样的电话桌。您可以添加LockedTime以添加时间标准。

create table phones (
  used bit default 0 not null,
  phone varchar(24) not null);

执行此查询仅提取一部电话,并且将其标记为已使用,不会返回两次。

set used = 1
output inserted.phone
where used = 0
;

请注意,它适用于MS SQL Server。其他一些SQL Server可能没有输出子句。

如果要将号码返回到免费号码池,则只需清除used标志。例如,您可以检查时间标准或任何其他确定电话免费的决定]

update phones set used = 0 where LockedTime < @somedatetime

© www.soinside.com 2019 - 2024. All rights reserved.