I have an IHttpHandler which I believe can benefit from re-use, because it is expensive to set up, and is thread-safe. But a new handler is being created for each request. My handler is not being re-used.
Following is my simple test case, without the expensive setup. This simple case demonstrates my problem:
public class MyRequestHandler : IHttpHandler
{
int nRequestsProcessed = 0;
public bool IsReusable
{
get { return true; }
}
public void ProcessRequest(HttpContext context)
{
nRequestsProcessed += 1;
Debug.WriteLine("Requests processed by this handler: " + nRequestsProcessed);
context.Response.ContentType = "text/plain";
context.Response.Write("Hello World");
}
}
Requests processed by this handler: 1
Requests processed by this handler: 1
Requests processed by this handler: 1
Requests processed by this handler: 1... at least 100 times. I never see > 1.
Am I misunderstanding how IsReusable works? Is there something else that can defeat re-use? My handler is being called from a Silverlight application if that makes any difference.
IsReusable is not a guarantee.
Just refactor your handler and put all cross-request state into a different class. Clearly separating cross-request state in a web application in best-practice anyway because it is dangerous.
If it's thread-safe, then you can go better than reuse anyway.
When IsReusable
returns true then:
ProcessRequest
is called.This means it could reduce the repeated set-up cost, but not necessarily (no guarantee) and not completely - if there are several concurrent calls to the same URI, then there'll need to be several such handlers created to handle them at the same time.
The good thing about this approach is that (when the pooling does happen), handlers don't actually have to be thread-safe.
Since yours is though, we can do better in one of two ways.
One, is to put all of your functionality into another class. Then the handler can just be a slim class where ProcessRequest
passes through to a static instance of that one.
Similarly, we can do this with your current class using an IHttpHandlerFactory:
public class MyRequestHandlerFactory : IHttpHandlerFactory
{
private static MyRequestHandler SingletonHandler = new MyRequestHandler();
IHttpHandler GetHandler(HttpContext context, string requestType, string url, string pathTranslated)
{
return SingletonHandler;
}
void ReleaseHandler(IHttpHandler handler)
{
//do nothing
}
}
With the above class, you can just change the Web.Config to refer to MyRequestHandlerFactory
where it currently refers to MyRequestHandler
, and it'll work perfectly.
(Unless you're not actually as thread-safe as you thought, in which case - oopsie!)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With