QueueBackgroundWorkItem与Task.Run,​​以执行后台任务

时间:2018-11-25 11:18:08

标签: c# multithreading wcf task-parallel-library backgroundworker

我不熟悉后台工作(通常在Task用法方面),并且对自己的实现方式有疑问。

(注意:如果您认为它太长了,请通过评论告知我,我将其缩短)

假设WCF服务返回货币汇率:

[ServiceBehavior(InstanceContextMode = InstanceContextMode.PerCall, ConcurrencyMode = ConcurrencyMode.Single)]
public class RatesServiceSvc : IGetRatesService
  • RatesServiceSvc取决于IRatesService(单音)。
  • IRatesService取决于IRatesQueueDispatcher。 拥有ratesCache字典。并在其构造函数中调用RunDispatcher(_ratesQueue, _dispatcherCancellationTokenSource);

IRatesService的内部实现是这样的:该服务实例化一个第三方队列,该队列从网络获取当前费率并将其作为事件推送到队列(无休止地)。为了获取事件,我需要调用运行backgroun循环的IRatesQueueDispatcher.Run(...)

IRatesService实现:

private void RunDispatcher(Queue queue, CancellationTokenSource dispatcherCancellationTokenSource)
    {
        Task<TaskCompletionCause> dispatcher = Task.Run(() => _queueDispatcher.Run(queue, dispatcherCancellationTokenSource.Token));
        dispatcher.ContinueWith((dispatcherTask) =>
        {
            HandleRunningTaskTermination(dispatcherTask.Result);
        });
    }

IRatesQueueDispatcher.Run()实现:

while (!cancellationToken.IsCancellationRequested && IsRatesQueueOk(eventsCount))
        {
            eventsCount = ratesQueueToDispatch.Dispatch();
            if (eventsCount < 0)
            {
                Thread.Sleep(_sleepTimeWhenReutersQueueEmpty);
            }
        }

queue.Dispach()调用导致调用(在同一线程中)EventClient.ProcessEvent(event)(在初始化阶段注册)的实现。从插入rateCache的事件中获取的数据(在本例中为ConcurrentDictionary

应用程序需要:

  • 后台循环将无休止地运行。
  • 如果后台循环由于某种原因而失败,我需要立即知道它。
  • 如果应用程序还有其他问题,我需要终止后台任务。

问题: 我用Task.Run(...).ContinueWith(...)运行背景的解决方案可以吗?我在一些地方读过有关“失火和遗忘”的危险(here  和here),我也知道.NET 4.5.2建议HostingEnvironment.QueueBackgroundWorkItem

但是我不确定这是否适合我。因为:

  1. 我需要从内部原因了解工作人员是否失败。

  2. 在我看来,HostingEnvironment.QueueBackgroundWorkItem的主要目的是保证在application_end之前完成正在运行的任务。就我的需求而言,在应用程序结束时运行后台工作没有任何意义,反之亦然-如果后台失败,则没有该应用程序就没有运行的意义。因此,我实现了HandleRunningTaskTermination()以通过调用System.Web.HttpRuntime.UnloadAppDomain();来回收应用程序。

毕竟,我担心自己的实现,并且正在寻找更好的解决方案。有更好的吗?

0 个答案:

没有答案