C# 异步运行操作方法

C# 异步运行操作方法,c#,asp.net-core-2.0,C#,Asp.net Core 2.0,我使用Asp.NETCore2,发现了一些“bug”,或者可能没有 我有一些行动方法,比如 public async Task<IActionResult> Index() { for (int k = 0; k < int.MaxValue / 2; k++) { await Task.Delay(0); } return View(); } 公共异步任务索引(){ 对于(int k=0;k

我使用Asp.NETCore2,发现了一些“bug”,或者可能没有

我有一些行动方法,比如

public async Task<IActionResult> Index() {
    for (int k = 0; k < int.MaxValue / 2; k++) { await Task.Delay(0); }
    return View();
}
公共异步任务索引(){
对于(int k=0;k

public IActionResult Index(){
对于(int k=0;k
所有这些延迟都等于5秒

如果我在浏览器中同时(一起)运行5个选项卡,最后一个选项卡将执行25秒。因为,它需要前面的标签

我在ASP.NETMVC4上写这段代码,5个标签执行5.5秒,而不是25秒

真不敢相信。无法解决它

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

这里的问题很可能与asp.net核心或web服务器无关,而与浏览器如何处理对同一url的并发请求有关。我不能告诉所有浏览器,所以将仅使用Chrome作为示例

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

因此,顺序处理请求的不是asp.net,而是web浏览器

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

[ResponseCache(Duration = 30)]
public IActionResult Index() {

    Thread.Sleep(5000);
    return Ok("test");
}
然后它将再次发出一个请求,在响应到达后(5秒),它将看到响应确实可以重用。然后,其他4个未决请求将立即得到解决(从缓存中)

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

[ResponseCache(NoStore = true)]
public IActionResult Index() {

    Thread.Sleep(5000);
    return Ok("test");
}
它将发出1个请求,在得到响应后,它意识到没有希望为后续请求重用响应(因为响应头禁止存储缓存)。然后它将同时发出挂起的4个请求

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


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

因为您正在等待每个异步方法,然后调用下一个,然后等待,等。将任务分配给变量,并在所有变量都关闭后等待。可能重复@john的问题是,通过启动五个不同的选项卡来运行五次代码不会并行。在一次代码运行中改变他等待的方式似乎不太可能影响这一点。@Rawling,是的,这是我的问题((这并不取决于等待变成行动。你是对的。导致它的确切行动是什么?我的意思是,你实际上没有使用问题中发布的代码,我猜,那么真正的代码是什么?非常感谢如此详细的描述,但我担心为什么在ASP.NET MVC 4中(例如)此问题不存在?@RomanReaLD您需要检查MVC4版本发送的响应头(使用fiddler或浏览器开发工具)。它可能设置了一些提到的缓存头。非常感谢,我在3浏览器中检查了一个url-它是realy async。我稍后将尝试ASP.NET MVC 4来检查此问题。再次感谢!!!@RomanReaLD如果您在检查后可以在此处对MVC 4检查的结果进行评论,那就太好了。
[ResponseCache(NoStore = true)]
public IActionResult Index() {

    Thread.Sleep(5000);
    return Ok("test");
}