我正在使用.net核心EF,并希望确保一次只有一个线程正在执行某个代码块,该代码块具有将数据更新到数据库的逻辑:
public async Task<IActionResult> ApproveEntity([FromBody] Entity[] entities)
{
Entity Entity = entities.Where(f => f.isMainEntity == true).First();
try
{
try
{
try
{
if (this.ValidateConcurrencyForWriteBack(Entity))
{
return this.BadRequest("Concurrency Error : Somebody else has already done this action. Please refresh and try again.");
}
else
{
try
{
if (Entity.SupportingDocuments?.Count > 0)
{
await this.UploadDocumentsToBlob(Entity, user);
this.Uow.Commit();
}
}
catch (Exception ex)
{
throw;
}
await this.BulkChallengeApproveReject(entities, user);
}
}
}
catch (DbUpdateConcurrencyException ex)
{
}
}
catch (Exception ex)
{
}
return this.Ok(Entity);
}
我希望上面的代码块一次只能由一个线程执行。
我尝试使用 Mutext 和 SemaphoreSlim ,但没有获得预期的结果。
validateConcurrency方法将检查记录是否已更新。但这并不能防止线程阻塞。
答案 0 :(得分:0)
提出该问题的技术解决方案。它不假装是正确的体系结构。
如果您有多个await
调用,则不能确定所有这些调用都将在同一线程上执行。这些是异步模式的原理。如果要在同一(而不是在单个)线程上调用inner方法,则必须摆脱内部await
的调用,使适当的方法同步(不要进行同步包装,因为它可能导致到死锁Should I expose synchronous wrappers for asynchronous methods?),只在顶层保留一个await
。
public async Task<IActionResult> ApproveEntity([FromBody] Entity[] entities)
{
return await Task.Run<IActionResult>(() =>
{
try
{
//Do synchronisation if needed here.
try
{
try
{
if (this.ValidateConcurrencyForWriteBack(Entity))
{
return this.BadRequest("Concurrency Error : Somebody else has already done this action. Please refresh and try again.");
}
else
{
try
{
if (Entity.SupportingDocuments?.Count > 0)
{
this.UploadDocumentsToBlob(Entity, user);//Change method to be synchronous.
this.Uow.Commit();
}
}
catch (Exception ex)
{
throw;
}
this.BulkChallengeApproveReject(entities, user);//Change method to be synchronous.
}
}
}
catch (DbUpdateConcurrencyException ex)
{
}
}
catch (Exception ex)
{
}
return this.Ok(Entity)
});
}