6

我有可重用的 HTTPHandlers 的问题。我想检查该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++);
    }

}

它们都按预期工作:Reusable 每次返回递增值,而 NonReusable 每次返回 0。但是当我将我的处理程序用作 WebHandlers (*.ashx) 时,它们每次都返回 0(代码完全相同)。这是否意味着当我使用 WebHandlers 时该IsReusable属性被忽略?

4

1 回答 1

2

默认的 .NET 配置是使用该类型System.Web.UI.SimpleHandlerFactory来处理对 .NET 的请求*.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 框架中没有可以使用的工厂类来代替SimpleHandlerFactoryHandlerFactoryWrapper没有无参数构造函数),尽管您可以创建自己的。

于 2013-02-18T16:41:20.877 回答