Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

HTTPHandler and IsReusable with WebHandler

I have the problem with reusable HTTPHandlers. I wanted to check how does the IsReusable property work. So I've created two handlers:

Reusable:

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++);
    }

}

And not reusable:

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++);
    }

}

They both work as expected: Reusable each time returns incremented value, while NonReusable returns 0 every time. But when I use my handlers as a WebHandlers (*.ashx) they both return 0 every time (code exactly the same). Does it mean that when I use WebHandlers the IsReusable property is ignored?

like image 487
Lukasz Lysik Avatar asked May 13 '12 18:05

Lukasz Lysik


1 Answers

The default .NET configuration is to use the type System.Web.UI.SimpleHandlerFactory to handle requests for *.ashx. You can verify this by looking at Http Handlers section in IIS Manager.

If you look at the source code for this factory, you can see that it does not check the IsReusable property at all. It also is stateless - it does not cache the created instances. To instead see a factory class that is using this property, look at System.Web.Configuration.HandlerFactoryWrapper.

Now if you look at System.Web.HttpApplication.RecycleHandlers() you see that it just indirectly calls System.Web.IHttpHandlerFactory.ReleaseHandler() method (the factory cache mentioned in the next paragraph does no handler instance caching on its own). The application itself ignores IsReusable property (the factory is supposed to do that) and as was discovered before, the .ashx files use a factory that does not reuse instances.

It is also worth noting that System.Web.HttpApplication.GetFactory() seems to be using a cache but that cache will only store instance of the factory itself (if it is specified). If an explicit factory is not specified, the method will create the HandlerFactoryWrapper mentioned above (that will in turn cache the handler instances).

As far as I can see, there is no factory class in .NET framework that you can use instead of SimpleHandlerFactory (the HandlerFactoryWrapper does not have parameterless constructor) although you can create your own.

like image 97
Knaģis Avatar answered Sep 24 '22 07:09

Knaģis