我遇到了可重用HTTPHandler的问题。我想检查一下IsReusable
属性是如何工作的。所以我创建了两个处理程序:
可重复使用:
public class ReusableHandler : IHttpHandler
{
public bool IsReusable
{
get { return true; }
}
private int _counter;
public ReusableHandler()
{
_counter = 0;
}
public void ProcessRequest(HttpContext context)
{
context.Response.Write("Reusable: " + _counter++);
}
}
不可重复使用:
public class NonReusableHandler : IHttpHandler
{
public bool IsReusable
{
get { return false; }
}
private int _counter;
public NonReusableHandler()
{
_counter = 0;
}
public void ProcessRequest(HttpContext context)
{
context.Response.Write("NonReusable: " + _counter++);
}
}
它们都按预期工作:每次返回递增值时可重用,而NonReusable每次返回0。但是当我使用我的处理程序作为WebHandlers(* .ashx)时,它们每次都返回0(代码完全相同)。这是否意味着当我使用WebHandlers时,忽略IsReusable
属性?
答案 0 :(得分:2)
默认的.NET配置是使用类型System.Web.UI.SimpleHandlerFactory
来处理*.ashx
的请求。您可以通过查看IIS管理器中的Http Handlers部分来验证这一点。
如果查看此工厂的源代码,可以看到它根本不检查IsReusable
属性。它也是无状态的 - 它不会缓存创建的实例。要改为查看使用此属性的工厂类,请查看System.Web.Configuration.HandlerFactoryWrapper
。
现在,如果查看System.Web.HttpApplication.RecycleHandlers()
,您会发现它只是间接调用System.Web.IHttpHandlerFactory.ReleaseHandler()
方法(下一段中提到的工厂缓存本身没有处理程序实例缓存)。应用程序本身忽略IsReusable
属性(工厂应该这样做),并且如前所述,.ashx
文件使用不重用实例的工厂。
值得注意的是System.Web.HttpApplication.GetFactory()
似乎正在使用缓存,但该缓存只会存储工厂本身的实例(如果已指定)。如果未指定显式工厂,则该方法将创建上面提到的HandlerFactoryWrapper
(这将反过来缓存处理程序实例)。
据我所知,.NET框架中没有工厂类可以使用而不是SimpleHandlerFactory
(HandlerFactoryWrapper
没有无参数构造函数),尽管您可以创建自己的工厂类。