繁体   English   中英

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

[英]Difference between HostingEnvironment.QueueBackgroundWorkItem and HostingEnvironment.RegisterObject

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

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.QueueBackgroundWorkItemHostingEnvironment.RegisterObject有任何好处。

QueueBackgroundWorkItem实际上只是对RegisterObject一个美化调用。 它处理将Stop调用转换为CancellationToken ,可以由异步工作项使用,在发生故障时写入事件日志,以及其他一些簿记项。 它没有什么特别有意思的。 您可以使用Reflector或ILSpy浏览源代码,直到使用4.5.2源更新http://referencesource.microsoft.com/

如果您对自己执行所有簿记的复杂性感到满意,那么您无法继续使用RegisterObject 新API适用于想要更简单一点的消费者。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM