C# HttpTaskAsyncHandler-似乎会阻塞,但我知道有问题
在下面的代码中,有一个HttpTaskAsyncHandler调用doit,该doit先延迟5秒,然后将字符串写入浏览器 如果我打开了两个浏览器选项卡,并在这两个选项卡上调用此页面。第一个在5秒内响应,第二个在10秒内响应 为什么第二个请求要等待第一个请求完成?延迟只是为了表示工作所花费的时间C# HttpTaskAsyncHandler-似乎会阻塞,但我知道有问题,c#,asp.net,async-await,task,httptaskasynchandler,C#,Asp.net,Async Await,Task,Httptaskasynchandler,在下面的代码中,有一个HttpTaskAsyncHandler调用doit,该doit先延迟5秒,然后将字符串写入浏览器 如果我打开了两个浏览器选项卡,并在这两个选项卡上调用此页面。第一个在5秒内响应,第二个在10秒内响应 为什么第二个请求要等待第一个请求完成?延迟只是为了表示工作所花费的时间 public class MyHandler : HttpTaskAsyncHandler { public override bool IsReusable { get
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());
}
}
Async
并不意味着并发。定义Async
处理程序时,本质上意味着在线程等待调用时将其返回到线程池
您的情况是,IIS Express将请求排队。它这样做是因为它需要会话上的独占锁:
摘自
并发请求和会话状态
对ASP.NET会话状态的访问在每个会话中是独占的,这意味着如果两个不同的用户同时发出请求,则会同时授予对每个单独会话的访问权限。但是,如果对同一会话发出两个并发请求(通过使用相同的SessionID值),第一个请求以独占方式访问会话信息。第二个请求仅在第一个请求完成后执行。(如果由于第一个请求超过锁定超时而释放了对信息的独占锁定,则第二个会话也可以访问。)如果@Page指令中的EnableSessionState值设置为ReadOnly,则对只读会话信息的请求不会导致对会话数据的独占锁定。但是,对于会话数据的只读请求可能仍然必须等待会话数据的读写请求设置的锁才能清除
可能的选择:
- 在其他浏览器(或匿名模式)中执行第二个请求
- 禁用会话状态
异步
并不意味着并发。定义Async
处理程序时,本质上意味着在线程等待调用时将其返回到线程池
您的情况是,IIS Express将请求排队。它这样做是因为它需要会话上的独占锁:
摘自
并发请求和会话状态
对ASP.NET会话状态的访问在每个会话中是独占的,这意味着如果两个不同的用户同时发出请求,则会同时授予对每个单独会话的访问权限。但是,如果对同一会话发出两个并发请求(通过使用相同的SessionID值),第一个请求以独占方式访问会话信息。第二个请求仅在第一个请求完成后执行。(如果由于第一个请求超过锁定超时而释放了对信息的独占锁定,则第二个会话也可以访问。)如果@Page指令中的EnableSessionState值设置为ReadOnly,则对只读会话信息的请求不会导致对会话数据的独占锁定。但是,对于会话数据的只读请求可能仍然必须等待会话数据的读写请求设置的锁才能清除
可能的选择:
- 在其他浏览器(或匿名模式)中执行第二个请求
- 禁用会话状态