如何在net core 3中同步任务之间的方法调用
How to synchronize a method call between tasks in net core 3
在我的应用程序中,我有一个 BackgroundService,它还包括以下方法:
- GetNumberAsync() 从数据库中获取 "oldest" 记录并更新记录的属性。
此方法是从 API 控制器异步方法调用的,例如:
[HttpGet]
[Route("GetNumber")]
public async Task<ActionResult<string>> GetNumber()
{
return Ok(await _numberService.GetNumberAsync());
}
恐怕如果同时调用 GetNumberAsync() 两次或更多次,那么其中一些可能会得到相同的记录。如何避免它,因为每个调用都应该 return 一个唯一的记录?
方法代码:
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 "";
}
谢谢。
这里是您如何实施它的想法。
假设您有 phone 个 table 像这样。您可以添加 LockedTime 以添加时间标准。
create table phones (
used bit default 0 not null,
phone varchar(24) not null);
执行此查询以仅提取一个 phone,它不会被 returned 两次,因为它被标记为已使用。
update top(1) phones
set used = 1
output inserted.phone
where used = 0
;
请注意,它适用于 MS SQL 服务器。其他一些 SQL 服务器可能没有输出子句。
如果你想return一个号码到免费号码池你只需要清除used
标志。
例如,您可以检查时间标准或任何其他决定 phone 变为空闲
update phones set used = 0 where LockedTime < @somedatetime
在我的应用程序中,我有一个 BackgroundService,它还包括以下方法:
- GetNumberAsync() 从数据库中获取 "oldest" 记录并更新记录的属性。
此方法是从 API 控制器异步方法调用的,例如:
[HttpGet]
[Route("GetNumber")]
public async Task<ActionResult<string>> GetNumber()
{
return Ok(await _numberService.GetNumberAsync());
}
恐怕如果同时调用 GetNumberAsync() 两次或更多次,那么其中一些可能会得到相同的记录。如何避免它,因为每个调用都应该 return 一个唯一的记录?
方法代码:
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 "";
}
谢谢。
这里是您如何实施它的想法。
假设您有 phone 个 table 像这样。您可以添加 LockedTime 以添加时间标准。
create table phones (
used bit default 0 not null,
phone varchar(24) not null);
执行此查询以仅提取一个 phone,它不会被 returned 两次,因为它被标记为已使用。
update top(1) phones
set used = 1
output inserted.phone
where used = 0
;
请注意,它适用于 MS SQL 服务器。其他一些 SQL 服务器可能没有输出子句。
如果你想return一个号码到免费号码池你只需要清除used
标志。
例如,您可以检查时间标准或任何其他决定 phone 变为空闲
update phones set used = 0 where LockedTime < @somedatetime