HttpTaskAsyncHandler - 似乎阻止但我知道出了什么问题

时间:2017-01-08 23:27:16

标签: c# asp.net async-await task httptaskasynchandler

在下面的代码中有一个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());
    }

}

1 个答案:

答案 0 :(得分:0)

Async并不意味着并发。定义Async处理程序时,它实质上意味着在调用awaiting时将线程返回给线程池。

在您的情况下发生的是IIS Express将请求排队。这样做是因为它需要对会话进行独占锁定:

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

  

并发请求和会话状态

     

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

可能的选择:

  • 在其他浏览器(或隐身模式)中执行第二个请求
  • 禁用SessionState