1

I am looking for clarification on the answers to this question.

The top two answers are somewhat contradictory on the thread safety requirements of a reusable handler.

Can a IHttpHandler instance be used to process multiple requests concurrently, requiring it to be fully thread safe?

or

Will it only ever process multiple requests consecutively, requiring only that the state of the handler is not changed in the ProcessRequest method?

Update (6/5/15):

I have been reviewing the source code for HttpApplication again here to try and get a answer to this.

My take is:

Requests are mapped to IHttpHandlers by a HttpApplication instance in MapHttpHandler.

MapHttpHandler uses a collection of HanlderFactoryCache's private to the HttpApplication instance. See GetFactory.

HanlderFactoryCache returns a HttpHandlerWrapper for IHttpHandler mappings, which manages a single IHttpHandler instance, and the IsReusable property is handled in HttpHandlerWrapper.ReleaseHanlder.

So any reuse of a handler will be scoped to a HttpApplication instance and as HttpApplication instances are not used concurrently (see Life Cycle Events and Global.asax file here) this all suggests:

  • Returning true from IHttpHanlder.IsReusable leverages the existing HttpApplication object pool to reuse instances of the IHttpHanlder.
  • IHttpHanlders do not have to be thread safe to take advantage of the built in instance reuse in ASP.NET.

The issue is if I'm wrong I could create some pretty big problems for myself and lots of people who have an opinion on this subject seem to think I'm wrong.

Can anyone show me where I've read the code wrong? Can anyone confirm my interpretation?

Note: I'm further convinced by the fact HttpApplication itself is a reusable IHttpHanlder that does not appear to be thread safe.

Community
  • 1
  • 1
Dave Manning
  • 820
  • 4
  • 11

1 Answers1

0

A reusable handler instance can be called concurrently. This answers your question.

is reset at the start or end of a request

I'm not sure what you mean. Certainly instance fields are not reset. What mechanism is supposed to do this and why? This might put the instance into an invalid state. That makes no sense.

Simply never create a reusable handler and the question becomes moot. There is never a reason to do it. It is a design flaw in ASP.NET. Always return false;.

If you want to maintain state (which is a solution of last resort in ASP.NET) do it outside of the handler instance so that concurrency issues are obvious to spot and to resolve. A handler should have zero instance fields.

usr
  • 168,620
  • 35
  • 240
  • 369
  • Have you got any reference/documentation stating the instance can be called concurrently? – Dave Manning Feb 25 '15 at 21:51
  • It's the best I could find out using Reflector. I did not try hard since this question is moot. – usr Feb 25 '15 at 21:53
  • OK thanks, I came to the other conclusion looking at the source code but was not sure, so was looking for some documentation to confirm. The handler I was working on has some initialisation in the constructor based on the folder structure of the website it is running in. I was looking at marking it as reusable as there is no need to repeat the initialisation for each request. – Dave Manning Feb 25 '15 at 22:15
  • If you just move the initialization into a `static Lazy` field all issues are gone. ASP.NET is not good at managing your state. I believe there can be multiple "reusable" instances at the same time. At least this is what a quick test showed. I could not reproduce any reuse at all but the test was not highly conclusive. – usr Feb 25 '15 at 22:19
  • Yeah what I got from the source is each HttpApplication instance would create it's own handlers and a HttpApplication instance does not process a request concurrently hence neither will a IHttpHandler. A static Lazy object would need to be thread safe which I was hoping was not a requirement of reusable handlers. I was looking at reusing a instance of a UriTemplateTable, which is not thread safe. Recreating this for each request wasn't a big deal but I was just curious as to how it works. – Dave Manning Feb 25 '15 at 23:12
  • Maybe you are looking for an object pool. You seem to want concurrent execution from the point of view of incoming requests yet single-threaded execution on each object. I understand the state you want to share is mutable? (If not I don't get the problem you seem to have with using Lazy). – usr Feb 26 '15 at 09:38
  • Actually, I think this question is done but I feel you could benefit from another question where you ask how to best manage that concrete piece of state that you have there. Leave a link here if you want. – usr Feb 26 '15 at 09:38