Я новичок в фоновой работе (и, как правило, в использовании задач) и у меня есть сомнения по поводу моей реализации.
(Примечание: если вы считаете, что это слишком долго, дайте мне знать по комментарию, и я будусократить его)
Предположим, служба 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
но я не уверен, что это подходящее решение для меня.Потому что:
Мне нужно знать, не сработал ли работник по своей внутренней причине.
Мне кажется, что основная цель HostingEnvironment.QueueBackgroundWorkItem
означает завершение выполнения задачи до application_end
.Для моих нужд Нет смысла запускать фоновую работу, когда приложение заканчивается, а также наоборот - если фон не работает, нет смысла запускать приложение без него.По этой причине я реализовал HandleRunningTaskTermination()
, чтобы перезапустить приложение, вызвав System.Web.HttpRuntime.UnloadAppDomain();
.
В конце концов, я беспокоюсь о своей реализации и ищу лучшее решение,Там лучше ??