Mil*_*adi 2 c# multithreading thread-synchronization async-await asp.net-core
我使用 ASP.NET Core Identity,通过 Jmeter 应用程序,我向我的 Web 应用程序发送多个请求以创建用户,它使用同一电子邮件创建了多个用户,尽管我的RequireUniqueEmail是true
services.AddIdentity<User, Role>(identityOptions =>
{
identityOptions.User.RequireUniqueEmail = true;
});
Run Code Online (Sandbox Code Playgroud)
当我一一发送请求时,一切正常,并在这段代码中给我重复的电子邮件错误
var result = await _userManager.CreateAsync(userToCreate, userPassword);
Run Code Online (Sandbox Code Playgroud)
但是当我使用 Jmeter 发送多个请求时,上面的代码无法处理重复的电子邮件,并且在 Jmeter 请求完成后,我打开 SQL Server,我看到至少创建了 10 条具有相同电子邮件的记录。我搜索了这个问题并得到了这个解决方案Using lock
private static readonly object lockObj = new object();
lock(lockObj)
{
var result = await _userManager.CreateAsync(userToCreate, userPassword);
}
Run Code Online (Sandbox Code Playgroud)
但它给了我错误并说“你不能在锁定语句中使用await”,第二个问题是ASP.NET Core Identity没有用于创建的Sync方法。如何在 ASP.NET Core Identity 中创建 create 的同步方法?
首先,你不能使用lock带有await关键字的语句!在你的情况下,也许最好使用对象,因为一次SemaphoreSlim只有一个请求可以进入关键部分(在WaitAsync和之间)!Release
private static readonly SemaphoreSlim semaphore = new SemaphoreSlim(1);
// rest of your code
async Task CreateUserAsync(User userToCreate, string userPassword)
{
await semaphore.WaitAsync();
try
{
var result = await _userManager.CreateAsync(userToCreate, userPassword);
}
finally
{
semaphore.Release();
}
}
Run Code Online (Sandbox Code Playgroud)
如果需要同步版本,还可以创建一个包装方法,封装异步调用并阻塞执行,直到操作完成。