kaycee
kaycee

Reputation: 911

How to use Hangfire job queuing for processing requests from ASP.NET HttpHandler?

I'm trying to use Hangfire to queue processing of data acquired via a HttpHandler.

The Hangfire server is correctly configured and works fine with simple functions like the ones explained here.

I can't seem to find a way to use my HttpContext data to work with Hangfire.

This code works:

public void ProcessRequest(HttpContext context)
        {
            var jobId = BackgroundJob.Enqueue(
                () => Console.WriteLine("HELLO")
            );
        }

This code does not works:

public void ProcessRequest(HttpContext context)
        {
            var jobId = BackgroundJob.Enqueue(
                () => doServerSideWork(context)
            );
        } 

public void doServerSideWork(HttpContext context)
        {
            context.Response.ContentType = "text/plain";
            context.Request.InputStream.Position = 0;
            var jsonString = String.Empty;
            using (var inputStream = new StreamReader(context.Request.InputStream))
            {
                jsonString = inputStream.ReadToEnd();
            }
            context.Response.Write(jsonString);
        }

I'm getting a BackgroundJobClientException:

{"Self referencing loop detected for property 'Context' with type 'System.Web.HttpContext'. Path 'ApplicationInstance'."}

After reading on the subject, it seems like a HttpContext can't be serialized, which is the first step in the job management Hangfire do (see previous link).

How can I use Hangfire to treat my HTTP requests ?

Upvotes: 0

Views: 1949

Answers (1)

Jesse Carter
Jesse Carter

Reputation: 21147

Short answer: It's impossible

Longer answer: It is inherently impossible to serialize an HttpContext and act on it later. If the "background work" you're trying to do is as simple as the code snippet you've shown you should be using async/await to avoid blocking threads and keep your server as responsive as possible. If the background work is actually CPU bound and it's not feasible for you to use async/await you need to extract the data from the HttpContext that is relevant for starting your work and pass that instead. In this case you should return a response to the client immediately, providing them with a callback address where they can either poll for updates or be notified in realtime with something like a websocket when the job completes.

Upvotes: 3

Related Questions