ApplicationShutdownMethod -> HangFireConfig -> Stop() called prematurely

I have a project that adds a job calling on a logic class that is only used by hangfire. The interface ioc is done in a
default request scope.

Bind<IBackgroundTaskLogic>().To<BackgroundTaskLogic>();

Adding to the queue

private static void ConfigureRecurringTasks()
{
    RecurringJob.AddOrUpdate<IBackgroundTaskLogic>("CleanUpOldStuff", l => l.CleanUpOldStuff(), Cron.Hourly);
}

This leads to ApplicationShutdownMethod being called after a few seconds, and Stop() in the HangFireConfig.
Stop() will throw a System.ObjectDisposedException. (seems like some ioc retainscope issue)

Project in Mvc 4.5 Im also using WebActivatorEx not WebActicator.

If I, however, use a logic class that is used by my project elsewhere, all is well. ???
It seems like this issue only occurs when the logic-class is used by hangfire exclusively
Any idea, why this might happen?

It is very, very interesting issue. I have a lot of questions to you :smile:

  1. Please, tell me versions of .NET and ASP.NET MVC.
  2. Ensure you are running your app using integrated pipeline.
  1. What IoC container do you use?

Background jobs have no access to the request context at all, you should use the separate registration for HF. Otherwise this may cause resolving exceptions. But they can not lead to application shutdown method, because I crafted every background thread very carefully to avoid your application to be terminated on HangFire failures.

Hmm, the default HangFireConfig class does not contain a call to the Dispose method (that exception is throwing only in this case).

  1. Are you calling it explicitly? If no, do you know who is calling it?
  2. Where AspNetBackgroundJobServer instance is declared, it is a local variable or a static field (to prevent GC)?

Please paste the whole HangFire initialization logic here.

  1. Where do you call the ConfigureRecurringTasks method?

Thanks for the reply @odinserj. All my ioc was done in request scope and I did no seperate registration for hangfire. Im now using a seperate kernel with in thread scope bindings for hangfire and all seems to be working.

The reason for it occational working on the same bindings I’m not completely sure. Guess it must have been some lucky bindings in transient scope.

Im using ninject for ioc and .Net 4.5.1 , not that it matters anymore.

Thanks for your awsome project Sergey, the dashboard is supersweet :smile:

Great, but I’m very concerned about your ObjectDisposedException in HangFireConfig.Stop method. Can you prove it by sending the full call stack of this exception?

There is no call stack. Stop() is called from external code

A first chance exception of type ‘System.ObjectDisposedException’ occurred in HangFire.Core.dll

Message: Cannot access a disposed object.
Object name: ‘HangFire.Server.ServerSupervisor’.
StackTrace: at HangFire.Server.ServerSupervisor.CheckDisposed()
at HangFire.Server.ServerSupervisor.Stop()
at HangFire.BackgroundJobServer.Stop()
at Juridisk.Web.HangFireConfig.Stop() in c:\xxx\xxx.Web\App_Start\HangFireConfig.cs:line 50
InnerException: null

Thanks for the reply! This is very strange thing that I can not understand. This exception is being thrown when someone calls the Stop or Start methods after the Dispose methods invocation. Default HangFireConfig class does not call the Dispose method at all.

Do you have explicit calls to the (AspNet)BackgroundJobServer.Dispose in your code? If so, can you show me where it is being called?

I’m asking you, because wrong container registrations should not cause such things to happen, and I’m trying to determine whether this issue is related to Hangfire itself. Please help me to investigate it.

I have no explicit call to Dispose objects in my code.

When the The ObjectDisposedException occurs, all registration of modules are done in a requestscope to prevent circular reference.

Not sure if the scope can cause the problem. Seems to work fine when I use request scope running hangfire on the separate kernel