1

在下面的代码中,有一个 HttpTaskAsyncHandler 调用 doit 首先延迟 5 秒并将字符串写入浏览器。

如果我打开了两个浏览器选项卡并在两者上调用此页面。第一个在 5 秒内响应,第二个在 10 秒内响应。

为什么第二个请求要等待第一个完成?延迟只是代表完成工作所花费的时间。

public class MyHandler : HttpTaskAsyncHandler
{
    public override bool IsReusable
    {
        get
        {
            return true;
        }
    }

    public override Task ProcessRequestAsync(HttpContext p_ctx)
    {
        return doit(p_ctx);
    }

    static int _count = 0;
    async Task doit(HttpContext p_ctx)
    {
        await Task.Delay(5000);
        p_ctx.Response.Write("doit " + (++_count).ToString());
    }

}
4

1 回答 1

0

Async不代表并发。当您定义一个Async处理程序时,它本质上意味着您awaiting在调用时将线程返回到线程池。

您的情况是 IIS Express 将请求排队。它这样做是因为它需要对会话进行排他锁:

摘自http://msdn.microsoft.com/en-us/library/ms178581.aspx

并发请求和会话状态

每个会话对 ASP.NET 会话状态的访问是独占的,这意味着如果两个不同的用户发出并发请求,则同时授予对每个单独会话的访问权限。但是,如果对同一个会话发出两个并发请求(通过使用相同的 SessionID 值),则第一个请求将获得对会话信息的独占访问权。第二个请求仅在第一个请求完成后执行. (如果因为第一个请求超过锁定超时而释放了对信息的独占锁,则第二个会话也可以获得访问权限。)如果 @Page 指令中的 EnableSessionState 值设置为 ReadOnly,则请求只读会话信息不会导致对会话数据的独占锁定。但是,会话数据的只读请求可能仍需要等待会话数据的读写请求设置的锁定清除。

可能的选项:

  • 在不同的浏览器(或隐身模式)中执行第二个请求
  • 禁用会话状态
于 2017-01-08T23:42:12.047 回答