为啥我对 web.api 的请求被长时间运行的控制器代码阻止?
Posted
技术标签:
【中文标题】为啥我对 web.api 的请求被长时间运行的控制器代码阻止?【英文标题】:Why are my requests to web.api being blocked by long running controller code?为什么我对 web.api 的请求被长时间运行的控制器代码阻止? 【发布时间】:2015-07-15 10:56:56 【问题描述】:我正在本地开发环境中使用 Angular 向 Web.API(IIS 8.5 托管)发出 ajax 调用。我同时通过不同的角度控制器进行 5 次调用,每个调用如下所示:
$scope.medications = API.Client.MedicationProfiles.query( clientId: clientId );
API 服务对 Client.MedicationProfiles 资源有以下定义:
this.Client.MedicationProfiles = $resource(
'/Noteable.API/api/Client/:clientId/MedicationProfiles/:id',
clientId: '@clientId',
id: '@Id'
,
update: method: 'PUT'
);
当页面加载时,我可以使用 chrome 开发工具看到所有发送到服务器的请求,但看起来它们一次返回一个,就好像它们是同步运行的一样。我在其中一个 Web.API 控制器操作中放置了一个 thread.sleep,果然,在该操作之后发出的所有调用都无法返回,直到休眠的调用返回。这对我来说没有任何意义,我想知道是否有人可以告诉我在什么情况下他们会期望这个。
【问题讨论】:
你能分享你的 web api 控制器代码吗? 【参考方案1】:这可能是在您的 Web api 后端实现异步模式的好情况 - 一旦 ajax 调用阻塞您的控制器,您将得到缓解。这可以通过利用async
和await
模式来实现。您需要返回一个 Task
,它代表一个异步操作。
一个例子可能包括...
public async Task<IHttpActionResult> Put(string clientId)
var response = await this.yourService.yourSavingMethod(clientId);
return Ok(response);
另请参阅 SO 问题 Why is this web api controller not concurrent? 了解有关该问题的更多详细信息和见解。此外,可以更改 ASP.NET 会话状态的默认行为以适应并发请求。一个例子可能包括
HttpContext.Current.SetSessionStateBehavior(SessionStateBehavior.ReadOnly)
ASP.NET Session State Overview
【讨论】:
具体来说,我们在 web.api 中启用了会话。由于需要会话访问权限,来自同一会话的并发调用被锁定。 刚刚了解了您后端的会话细节,我将添加答案。在没有所有有问题的细节的情况下,不得不对你的 api 实现做出最好的猜测@sonicblis @sonicblis:如果会话阻碍了你,最简单的解决方案是改变你处理会话的方式。例如here is a post详细说明了如何为会话分配只读,多个只读请求可以并行运行。 是的,已经改成HttpContext.Current.SetSessionStateBehavior(SessionStateBehavior.ReadOnly)
并且工作得很好。【参考方案2】:
我认为您的问题是由浏览器或 ASP.NET 引起的。如果是 ASP.NET,请查看此线程:
C# Web API - Blocking
如果是您的浏览器,请使用示例代码查看此线程:
Why is my async ASP.NET Web API controller blocking the main thread?
【讨论】:
必须强调浏览器原因。我疯了,不明白为什么我的 ASP.NET Core Web API 会在单个线程上处理请求,为什么看起来甚至等待/异步阻塞......然后结果证明 Chrome 只是在延迟当多个标签指向同一个地址时请求。以上是关于为啥我对 web.api 的请求被长时间运行的控制器代码阻止?的主要内容,如果未能解决你的问题,请参考以下文章
用于运行调度程序长时间运行任务的 Web Api 或 WCF