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

asp.net-core async-await c# entity-framework-core thread-synchronization

Question

In my application I have a BackgroundService which also includes the following method:

  • GetNumberAsync() gets the "oldest" record from database and updates the properties of the record.

This method is called from API controller async method like:

[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. 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.

1
0
3/1/2020 12:05:30 AM

Accepted Answer

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.

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. Some other SQL servers might not have output clause.

If you want to return a number to the free number pool you just need to clear the used flag. 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

0
2/29/2020 11:21:13 PM


Related Questions





Related

Licensed under: CC-BY-SA with attribution
Not affiliated with Stack Overflow
Licensed under: CC-BY-SA with attribution
Not affiliated with Stack Overflow