代永波

导航

 

在ASP.net 中,可以编写一个Class 继承IHttpHandler,其中有个IsReusable属性,表示是否可以重用。

我的疑问是:并发时,HttpHandlers可以重用吗?

1 调用原理

HttpHandler的调用原理是HttpApplication的ResumeSteps函数首先算出本请求应该用哪个IHttpHandler实例来执行请求,然后调用IHttpHandler的ProcessRequest方法执行请求。

 

反射看下源代码:

MapHandlerExecutionStep的Execute函数:

ResumeSteps函数的最后还有一句RecycleHandlers()调用,用来决定下次是否可重用这个IHttpHandler的实例:

根据IsReusable属性的值,决定是否销毁(没销毁,则下次直接使用,销毁了,自然不能重用了)

2 并发多个请求是否可以重用?

ASP.net执行请求的先是HttpApplication,然后由HttpApplication调用IHttpHandler执行ProcessRequest方法。

如果并发多个请求,则会创建多个HttpApplication的实例,这样新的HttpApplication的实例上,并没有Handler的实例缓存,所以会创建新的Handler的实例。

当然,这个2个请求结束后,HttpApplication的实例会被回收重用,下次请求进来,将使用已初始化好的Handler的实例。

3 调试证明:

  1. 准备一个Handler,传入的参数不同,执行不同的动作:
public class MyCallBack : IHttpHandler
{
	public bool IsReusable
	{
		get { return true; }
	}
	public void ProcessRequest(HttpContext context)
	{
		string name = context.Request.QueryString["Method"];
		if (name == "Default") {
			Default();
		}
		else if (name == "Test")
		{
			Test();
		}
		else
		{
		}
	}
	 
	public void Default()
	{
		Thread.Sleep(10000);
		HttpContext.Current.Response.Write("Default");
	}
	public void Test()
	{
		HttpContext.Current.Response.Write("Test");
	}
}

 

2) 配置到Web.Config

        <httpHandlers>
            <add verb="GET" path="MyCallBack.axd" type="MyCallBack"/>
        </httpHandlers>

3) 启动调试:

第一次请求,实例为:6757235

第二次请求,实例还是:6757235,证明实例是被重用的

第三次请求,实例还是:6757235,继续执行,让它卡住。

同时再发一次请求,结果能顺利命中Test

但是实例变了,原因是这个实例是另外一个HttpApplication 实例创建的。

4结论:

IHttpHandler的实例重用是在HttpApplication的基础上,即便重用,也不能保证整个Web应用程序中只有1个HttpHandler的实例。

如果某个方法执行很久,它不会拖累别的请求,原因是别的请求是在另外一个HttpApplication实例上工作的,当前执行很久的请求并不在同一个实例上。

posted on 2014-10-04 00:46  代永波  阅读(338)  评论(0编辑  收藏  举报