简体   繁体   English

如何在net core 3中的任务之间同步方法调用

[英]How to synchronize a method call between tasks in net core 3

In my application I have a BackgroundService which also includes the following method:在我的应用程序中,我有一个 BackgroundService,其中还包括以下方法:

  • GetNumberAsync() gets the "oldest" record from database and updates the properties of the record. GetNumberAsync()从数据库中获取“最旧”的记录并更新记录的属性。

This method is called from API controller async method like:此方法是从 API 控制器异步方法调用的,例如:

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

I'm afraid that if two or more calls of GetNumberAsync() at the same time occurs then some of them may get the same record.恐怕如果同时发生两次或多次GetNumberAsync()调用,那么其中一些调用可能会得到相同的记录。 How to avoid it, because every call should return a unique record?如何避免它,因为每个调用都应该返回一个唯一的记录?

Method code:方法代码:

    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 "";
    }

Thanks.谢谢。

Here's the idea how you can implement it.这是如何实现它的想法。

Assuming you have phones table like this.假设你有这样的电话桌。 You might add LockedTime to add a time criteria.您可以添加 LockedTime 以添加时间条件。

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

Execute this query to extract just one phone and it will not be returned twice as it marked as used.执行此查询以仅提取一部手机,并且不会在标记为已使用时返回两次。

update top(1) phones
set used = 1
output inserted.phone
where used = 0
;

Note that it works on MS SQL server.请注意,它适用于 MS SQL 服务器。 Some other SQL servers might not have output clause.其他一些 SQL 服务器可能没有输出子句。

If you want to return a number to the free number pool you just need to clear the used flag.如果您想将一个号码返回到空闲号码池,您只需要清除已used标志。 For example, you may do it checking the time criteria or any other deciding that a phone becomes free例如,您可以检查时间标准或任何其他决定手机免费的方法

update phones set used = 0 where LockedTime < @somedatetime

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM