QueueBackgroundWorkItem vs. Task.Run для фоновой задачи - PullRequest
0 голосов
/ 25 ноября 2018

Я новичок в фоновой работе (и, как правило, в использовании задач) и у меня есть сомнения по поводу моей реализации.

(Примечание: если вы считаете, что это слишком долго, дайте мне знать по комментарию, и я будусократить его)

Предположим, служба WCF, которая возвращает курсы валют:

[ServiceBehavior(InstanceContextMode = InstanceContextMode.PerCall, ConcurrencyMode = ConcurrencyMode.Single)]
public class RatesServiceSvc : IGetRatesService
  • RatesServiceSvc зависит от IRatesService (сингелтон).
  • IRatesService зависит от IRatesQueueDispatcher.содержит ratesCache словарь.и в своем конструкторе вызывает RunDispatcher(_ratesQueue, _dispatcherCancellationTokenSource);

Внутренняя реализация IRatesService выглядит следующим образом: служба создает стороннюю очередь, которая получает из сети текущие скорости и передает их как событияв очередь (бесконечно).Для извлечения событий мне нужно вызвать IRatesQueueDispatcher.Run(...), который запускает цикл backgroun:

Реализация 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 () Imlementation:

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

Вызов queue.Dispach() приводит к вызову (в том же потоке) реализации EventClient.ProcessEvent(event) (зарегистрированной на этапе инициализации).Данные, извлеченные из событий, вставленных в rateCache (в данном случае это ConcurrentDictionary)

Приложению необходимо:

  • Фоновый цикл будет выполняться бесконечно.
  • Если по какой-то причине фоновый цикл завершается неудачно, мне нужно немедленно его узнать.
  • Если у приложения возникает другая проблема, мне нужно убить фоновую задачу.

Вопрос: Есть лимое решение для запуска фоновой работы Task.Run(...).ContinueWith(...) в порядке?Я читал в некоторых местах об опасностях «Огонь и Забудь» ( здесь и здесь ), также я знаю, что .NET 4.5.2 предлагает HostingEnvironment.QueueBackgroundWorkItem

но я не уверен, что это подходящее решение для меня.Потому что:

  1. Мне нужно знать, не сработал ли работник по своей внутренней причине.

  2. Мне кажется, что основная цель HostingEnvironment.QueueBackgroundWorkItem означает завершение выполнения задачи до application_end.Для моих нужд Нет смысла запускать фоновую работу, когда приложение заканчивается, а также наоборот - если фон не работает, нет смысла запускать приложение без него.По этой причине я реализовал HandleRunningTaskTermination(), чтобы перезапустить приложение, вызвав System.Web.HttpRuntime.UnloadAppDomain();.

В конце концов, я беспокоюсь о своей реализации и ищу лучшее решение,Там лучше ??

...