Hangfire Discussion

Hangfire Is Executing Jobs Sequentially


#1

I am using HangFire hosted by IIS with an app pool set to “AlwaysRunning”. I am using the Autofac extension for DI. Currently, when running background jobs with HangFire they are executing sequentially. Both jobs are similar in nature and involve File I/O. The first job executes and starts generating the requisite file. The second job executes and it starts executing. It will then stop executing until the first job is complete at which point the second job is resumed. I am not sure if this is an issue related to DI and the lifetime scope. I tend to think not as I create everything with instance per dependency scope. I am using owin to bootstrap hangfire and I am not passing any BackgroundServer options, nor am I applying any hints via attributes. What would be causing the jobs to execute sequentially?


#2

If you’re not using anything like DisableConcurrentExecutionAttribute, the only reason could be your file IO (or some other inter-thread lock) which is blocking execution. Need more details about what kind of IO you’re performing, as it usually shouldn’t be an issue. Hard to tell without looking at the code.
But it is unlikely to be a DI issue, because even if DI container doesn’t create a new instance of a service for the jobs, it still should at least return an existing instance, so using it may only corrup internal state but not lock. Only if the service logic itself locks somewhere inside the implementation.


#3

The code is actually reading data from from a database and immediately writing to disk. Most of the code except for writing files is Async. Could the async code cause the issue?


#4

I have a file provider which creates a lock as follows to ensure thread safety when writing the file. Do you think this lock could be interfering with HangFire’s threading. My FileProvider is created per request and I would not think it should effect the external threading

 ReadWriteLock.EnterWriteLock();
        try
        {
            File.AppendAllText(path, text);
        }
        finally
        {
            // Release lock
            ReadWriteLock.ExitWriteLock();
        }