【问题标题】:Why are multiple calls to the same ApiController by single user handled synchronously?为什么单个用户对同一个 ApiController 的多次调用是同步处理的?
【发布时间】:2013-12-04 00:43:29
【问题描述】:

我做了一个简单的 GET 循环 10 次,每次迭代等待 1 秒来模拟工作。当我从 Chrome 中的一个选项卡调用此路由时,需要 10 秒(如预期的那样)。当我同时(从 2 个不同的选项卡)调用此路线时,第一个选项卡需要 10 秒才能完成,但第二个选项卡需要 20 秒。

如果我将第二个标签设为隐身标签,则两个请求同时运行时会在 10 秒内返回。我还注意到,如果我有 2 个不同的控制器(和 2 个不同的路由),来自 2 个非隐身标签的同时请求会同时返回。

有人可以解释为什么对同一个控制器的多个请求是同步处理的吗?

编辑:该网站目前在 IIS 中自托管

【问题讨论】:

  • 您的网站托管在什么平台上?
  • afaik 控制器已废弃,仅供一次性使用。
  • @DavidNeale 该站点在 IIS 中自托管
  • 从不同的客户端试试这个,你会得到两个 10 秒的响应。
  • @Maess 我认为问题出在我的设计上......我在同一个控制器中有多个 GET,我从 AJAZ 请求中得到了这些。我可能应该将这些调用转移到它们自己的控制器上

标签: c# asp.net-web-api


【解决方案1】:

ASP.NET 使用会话状态锁定来确保在给定时间在同一会话上只处理一个请求。这有助于防止会话状态周围出现竞争条件。

您可以通过使用SessionStateAttribute 告诉 ASP.NET 您不打算写入会话状态来获得更好的并发性。

请参阅this article 或this article 了解更多信息。

更新

由于您使用的是ApiController,因此上述行为可能不适用。但是,浏览器会进一步限制并发性,正如this post 的回答中所解释的那样。

【讨论】:

  • 所以,我假设如果我的所有控制器都继承自基本控制器(我已将特定于控制器的缓存抽象到基本控制器中),那么会话状态锁将是调用的原因这些控制器一次处理 1 个?有没有办法关闭会话状态锁定?
  • 感谢您的更新...不过有一件事。链接的文章说,处理独占锁定的一种方法是“使用类似 REST 的服务,如 ASP.NET WebAPI 或 WCF REST。因为 REST 本质上是无状态的,所以禁止使用会话状态。”我正在使用 WebAPI(这些是 ApiControllers),但我仍然受到影响。我是否仍应使用 SessionStateAttribute 显式标记控制器?
  • @Ryan:这很好。我认为 ApiControllers 无权访问会话。然而,大多数浏览器自愿限制对同一域的并发请求数(通常为 2 或 3)。您能否使用浏览器的开发工具来查看这是否可以解释您获得的并发级别?
  • 我同时从 Chrome 测试了 2 个连接,并且被限制为 1 个。我在 IE 中进行了相同的测试,并且能够同时获得结果。因此,在使用同一会话时,浏览器似乎一直在限制对同一路由的调用。
  • @Ryan:这很有趣。我想知道 Chrome 是否想在发送另一个请求之前查看结果是否可以缓存。如果向请求中添加缓存清除查询参数会发生什么?
猜你喜欢
  • 1970-01-01
  • 2015-02-11
  • 2020-03-13
  • 2017-01-19
  • 1970-01-01
  • 2011-09-23
  • 2019-05-15
  • 1970-01-01
  • 2016-04-12
相关资源
最近更新 更多