Difference between HostingEnvironment.QueueBackgroundWorkItem and HostingEnvironment.RegisterObject
.net, .net-4.5.2, asp.net, asp.net-mvc, c#
Solution
`QueueBackgroundWorkItem` is really just a glorified call to `RegisterObject` under the covers. It handles converting the call to `Stop` into a CancellationToken that can be consumed by asynchronous work items, writing to the event log in the case of failures, and a few other bookkeeping items. There's nothing terribly interesting about it. You can use Reflector or ILSpy to browse the source until http://referencesource.microsoft.com/ is updated with the 4.5.2 sources.
If you're comfortable with the complexity of performing all the bookkeeping yourself, there's no reason you can't continue to use `RegisterObject`. The new API is for consumers who want something a bit simpler.
Problem
Currently I am using `HostingEnvironment.RegisterObject` to run my background work in my MVC 5 app. Specifically I have, ``` public class BackgroundWorker { /// <summary> /// Runs a background task that is registered with the hosting environment /// so it is guaranteed to finish executing. /// </summary> /// <param name="action">The lambda expression to invoke.</param> public static void Run(Action action) { new IISBackgroundTask().DoWork(action); } /// <summary> /// Generic object for completing tasks in a background thread /// when the request doesn't need to wait for the results /// in the response. /// </summary> class IISBackgroundTask : IRegisteredObject { /// <summary> /// Constructs the object and registers itself with the hosting environment. /// </summary> public IISBackgroundTask() { HostingEnvironment.RegisterObject(this); } /// <summary> /// Called by IIS, once with <paramref name="immediate"/> set to false /// and then again with <paramref name="immediate"/> set to true. /// </summary> void IRegisteredObject.Stop(bool immediate) { if (_task.IsCompleted || _task.IsCanceled || _task.IsFaulted || immediate) { // Task has completed or was asked to stop immediately, // so tell the hosting environment that all work is done. HostingEnvironment.UnregisterObject(this); } } /// <summary> /// Invokes the <paramref name="action"/> as a Task. /// Any exceptions are logged /// </summary> /// <param name="action">The lambda expression to invoke.</param> public void DoWork(Action action) { try { _task = Task.Factory.StartNew(action); } catch (AggregateException ex) { // Log exceptions foreach (var innerEx in ex.InnerExceptions) { Logger.Log(innerEx); } } catch (Exception ex) { Logger.Log(ex); } } private Task _task; private static readonly ILogger Logger = Loggers.Logger.Instance; } } ``` usage, ``` BackgroundWorker.Run(() => BackGroundMethod(); );// run this in a background thread ``` So, using `HostingEnvironment.QueueBackgroundWorkItem` has any benefit over `HostingEnvironment.RegisterObject`