Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Difference between HostingEnvironment.QueueBackgroundWorkItem and HostingEnvironment.RegisterObject

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

like image 756
Imran Qadir Baksh - Baloch Avatar asked Jun 01 '14 09:06

Imran Qadir Baksh - Baloch


1 Answers

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.

like image 109
Levi Avatar answered Oct 14 '22 16:10

Levi