异步运行操作方法



我使用 Asp.Net Core 2 并发现了一些"错误",也可能不是。

我有一些操作方法,例如

public async Task<IActionResult> Index() {
for (int k = 0; k < int.MaxValue / 2; k++) { await Task.Delay(0); }
return View();
}

public IActionResult Index() {
for (int k = 0; k < int.MaxValue; k++) {  }
return View();
}

所有这些延迟等于 5 秒。

如果我在浏览器中同时(一起)运行 5 个选项卡,最后一个选项卡执行 25 秒。因为,它使用了以前的选项卡。

我在 MVC 4 ASP.NET 编写此代码,5 个选项卡执行 5.5 秒,而不是 25 秒!!

我真不敢相信。并且无法解决它。

为什么 ASP.NET Core 2 中的操作会同步运行?怎么了? 我如何理解浏览器 ASP.NET Core 2的请求必须创建一个新的控制器实例,初始化它并执行该方法,这是真的吗? 可能是我配置了错误的项目?在哪里可以更改此选项?

这里的问题很可能与 asp.net 核心或 Web 服务器无关,而是与浏览器如何处理对同一 URL 的并发请求有关。我无法判断所有浏览器,因此仅使用Chrome作为示例。

您在 chrome 中打开了 5 个页面,所有页面都指向您服务器的同一网址。服务器处理此请求需要 5 秒。默认情况下,Chrome不会同时发出所有 5 个请求。相反,它只会发出 1,因为它认为它可能能够缓存响应并将其重用于其他 4 个请求。当第一个响应到达时,它看到不幸的是它无法重用它(因为您没有提供任何缓存标头)。然后发出具有相同希望的第二个请求,依此类推。结果,所有 5 个请求都逐个发出,希望响应可以重新用于后续请求。

因此,按顺序处理请求不是 asp.net - 而是 Web 浏览器执行此操作。

如果添加一些允许浏览器缓存响应的标头,例如:

[ResponseCache(Duration = 30)]
public IActionResult Index() {
Thread.Sleep(5000);
return Ok("test");
}

然后它将再次发出 1 个请求,并且在响应到达(5 秒)后,它会看到确实可以重用响应。然后其他 4 个待处理的请求将立即解决(从缓存中)。

或者,如果您说浏览器它不应该为此请求存储缓存:

[ResponseCache(NoStore = true)]
public IActionResult Index() {
Thread.Sleep(5000);
return Ok("test");
}

它将发出 1 个请求,在获得响应后,它意识到没有希望为后续请求重用响应(因为响应标头禁止存储缓存)。然后,它将同时发出挂起的 4 个请求。

当然,您不应该仅仅为了避免这种行为而使用上面提到的缓存标头 - 它们只是为了确认行为。

一般来说,你不应该担心这一点。有人不太可能在同一浏览器中打开您的网站 5 次,即使他们这样做了 - 在这种情况下等待很长时间不太可能是一个大问题。但是,如果您的应用程序以某种方式设计为这样使用 - 您确实可以使用缓存标头来避免这种情况。

最新更新