What is the correct pattern for gracefully shutting down running jobs when the app pool shuts down?

My app is correctly calling BackgroundJobServer.Stop() when the application is ended (via Application_End in Global.asax.cs).

This Stop() method is not blocking, however, so my running tasks seem to be killed before they can get a chance to respond to a cancellation request via a token (because they only do this at safe-points in their execution).

Do I need to manually sleep on the calling thread after stopping the job server, to allow running jobs a chance to cancel themselves? Or is there a better way of doing this? I haven’t been able to find any examples on this.

Thanks for the help.

Sam, this is a brilliant question. It turned out that documentation is wrong about this topic. There is a blocking method, but it is Dispose method and not Stop. So, you should call it, as with other implementors of IDisposable interface. I updated the documentation and registered a bug:

Thanks, that helps a lot - the Dispose() method is clearly blocking until running threads have joined, which is exactly what I want.