Is IHttpHandler ProcessRequest thread safe or not?

short answer: “Yes” with an “If,” long answer: “No” — with a “But.”
— Reverend Lovejoy

I was debugging a HttpHandler and came across many examples that stated ProcessRequest() is not thread safe, unless of course you’re doing something very simple, like the following:

public void ProcessRequest(HttpContext context)
{
    context.Response.Write("hello");
}

If, however, you’re doing anything with local variables (the examples say), you probably have a problem:

public void ProcessRequest(HttpContext context)
{
    var someValue = someFunction();
    context.Response.Write(someValue);
}

However, local variables are thread safe! So the above example is perfectly ok, even if someFunction() returns a different value each call, so long as it is, in itself, thread safe.

The obviously broken example would be:

public class AttachmentHandler : IHttpHandler
{
    private static int _callCnt = 0;

    public bool IsReusable
    {
        get { return true; }
    }

    public void ProcessRequest(HttpContext context)
    {
        context.Response.Write(_callCnt++);
    }
}

because all static variables (except thread static variables) are shared amongst all threads.

To demonstrate a working example, here’s an attachment handler which imposes a 10 second wait. Call it multiple times within 10 seconds and you should get a different value in the file each time:

public class AttachmentHandler : IHttpHandler
{
    public bool IsReusable
    {
        get { return true; }
    }

    public void ProcessRequest(HttpContext context)
    {
        Random r = new Random();
        double foo = r.Next();
        Thread.Sleep(10000);

        context.Response.ContentType = "text/plain";
        context.Response.AddHeader("Content-disposition", "attachment; filename=\"foo.txt\"");
        context.Response.BinaryWrite(Encoding.ASCII.GetBytes(string.Format("hello, universe {0}!", foo)));
        context.Response.Flush();
        HttpContext.Current.ApplicationInstance.CompleteRequest();
    }
}

So yes, ProcessRequest() is thread safe unless you reference (and maybe not even then) any thread unsafe objects, such as session, static variables, etc.