我正在使用 C# 和 .Net Framework 4.7 开发 ASP.NET Web Api 应用程序。
我在控制器中有一种方法,我只想一次仅由一个线程执行。换句话说,如果有人调用此方法,则另一个调用必须等待该方法完成。
我找到了这个所以答案 https://stackoverflow.com/a/42117694/68571那可以完成这项工作。但这里它使用一个队列,我不知道如何使用该队列。在该答案中解释说,我可以创建一个 Windows 服务来使用队列,但我不想在我的解决方案中添加另一个应用程序。
我想在 Web Api 方法中添加一个锁,如下所示:
[HttpPut]
[Route("api/Public/SendCommissioning/{serial}/{withChildren}")]
public HttpResponseMessage SendCommissioning(string serial, bool withChildren)
{
lock
{
string errorMsg = "Cannot set commissioning.";
HttpResponseMessage response = null;
bool serverFound = true;
try
{
[ ... ]
}
catch (Exception ex)
{
_log.Error(ex.Message);
response = Request.CreateResponse(HttpStatusCode.InternalServerError);
response.ReasonPhrase = errorMsg;
}
return response;
}
}
但我不认为这是一个好的解决方案,因为如果运行该方法出现问题,它可能会阻止大量待处理的调用,并且我将丢失所有待处理的调用,或者也许我错了,调用(线程)将等待直到其他结束。换句话说,我认为如果我使用 this 我可能会陷入僵局。
我正在尝试这样做,因为我需要按照收到的顺序执行调用。查看此操作日志:
2017-06-20 09:17:43,306 DEBUG [12] WebsiteAction - ENTERING PublicController::SendCommissioning , serial : 38441110778119919475, withChildren : False
2017-06-20 09:17:43,494 DEBUG [13] WebsiteAction - ENTERING PublicController::SendCommissioning , serial : 38561140779115949572, withChildren : False
2017-06-20 09:17:43,683 DEBUG [5] WebsiteAction - ENTERING PublicController::SendCommissioning , serial : 38551180775118959070, withChildren : False
2017-06-20 09:17:43,700 DEBUG [12] WebsiteAction - EXITING PublicController::SendCommissioning
2017-06-20 09:17:43,722 DEBUG [5] WebsiteAction - EXITING PublicController::SendCommissioning
2017-06-20 09:17:43,741 DEBUG [13] WebsiteAction - EXITING PublicController::SendCommissioning
在其中任何一个结束之前我收到三个电话:线程[12], [13] and [5]
. But 最后一个在第二个之前结束: [12], [5] and [13]
.
我需要一种机制来不允许这种情况发生。
我该如何确保呼叫按照我拨打的顺序进行处理?