HostingEnvironment.QueueBackgroundWorkItem和HostingEnvironment.RegisterObject之间的区别

6

目前我在我的MVC 5应用程序中使用HostingEnvironment.RegisterObject来运行后台工作。具体地说,我有以下内容:

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;
    }
}

使用方法,

 BackgroundWorker.Run(() => 
       BackGroundMethod();
 );// run this in a background thread

因此,使用HostingEnvironment.QueueBackgroundWorkItem相比HostingEnvironment.RegisterObject有什么好处?
1个回答

7
QueueBackgroundWorkItem实际上只是在内部调用RegisterObject的一种华丽写法。它处理将调用转换为CancellationToken以供异步工作项消耗,在失败的情况下写入事件日志以及其他一些簿记项目。它并没有什么特别有趣的地方。您可以使用Reflector或ILSpy浏览源代码,直到http://referencesource.microsoft.com/更新为4.5.2源代码。
如果您对自己执行所有簿记的复杂性感到舒适,那么您完全可以继续使用RegisterObject。新API适用于希望获得更简单东西的消费者。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接