Выполнение фоновых задач в ASP.NET MVC используя QueueBackgroundWorkItem

До недавних пор в ASP.NET не было встроенной поддержки фоновых задач. В интернете множество вопросов (например на Stack Overflow) с вопросами и решениями этой задачи. Это может потребоваться при отправке электронной почты, обработке изображения или формирования PDF файла с отчетом. 

Ранее имелись некоторые риски, при разработке фоновых задач. А именно

На помощь приходит QueueBackgroundWorkItem (QBWI), который был специально добавлен в .NET 4.5.2. Чтобы добавить поддержку небольших фоновых задач (с некоторыми ограничениями). QueueBackgroundWorkItem планирует задачу в фоновом режиме, независимо от запросов. Это отличает его от ThreadPool. Он будет считать сколько фоновых задач запущено сейчас и будет пытаться отложить выключение AppDomain, пока все задачи не будут выполнены. Объявлен следующим образом.

[SecurityPermission(SecurityAction.LinkDemand, Unrestricted =true)] 
public static void QueueBackgroundWorkItem(Action<CancellationToken> workItem);

Пример вызова QBWI.

public ActionResult SendEmail()
{  
  string info = "You Mail Here";

  HostingEnvironment.QueueBackgroundWorkItem(ct => SendEmail(info));
  return View();
}

Но использование этого механизма накладывает некоторые ограничения.

  1. QBWI нельзя вызвать вне ASP.NET управляемого AppDomain
  2. QBWI может отсрочить отключение AppDomain только на 90 секунд, поэтому механизм подходит только для выполнения небольних задач
  3. Обработчик вызываемый в фоне не имеет доступа к HttpContext. Поэтому всю необходимую информацию необходимо передавать в него самостоятельно
  4. Опять же, не гарантируется выполнения фоновых задач. Как только Application Pool начал завершение работ вызовы QBWI будут проигнорированы. Хорошая новостьи, что CancellationToken получит маркер с информацией о том, что Application Pool начал завершение работы. Разработчик должен приложить все усилия, чтобы получить этот маркер и правильно его обработать

Это еще один наглядный пример, что все возможные решения с фоновыми задачами в ASP.NET следует решать вне самого ASP.NET. Существует множество альтернативных решений, одно из них, например использовать Windows службы

Комментарии

comments powered by Disqus