异步运行操作方法

时间:2018-03-19 07:24:29

标签: c# asp.net-core-2.0

我使用Asp.Net Core 2并找到一些" bug"或者可能不是。

我有一些行动方法,比如

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

OR

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

所有这些延迟等于5秒。

如果我在浏览器的最后一个标签中同时(一起)运行5个标签25秒。因为它会影响之前的标签。

我在ASP.NET MVC 4上编写了这个代码,并且执行了5个标签5.5秒,而不是25秒!

我无法相信。并且无法解决它。

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

1 个答案:

答案 0 :(得分:1)

这里的问题很可能与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次,即使他们这样做了 - 在这种情况下等待的时间不太可能是一个大问题。但是,如果您的应用程序被设计为像这样使用 - 您可能确实使用缓存标头来避免这种情况。