Веб-страница выполняет длительную задачу без тайм-аута

На нашем сайте есть страница администратора, которая позволяет администраторам запускать процесс, который копирует страницу данного шаблона CMS в пару сотен каталогов. Я предполагаю, что этот процесс занимает несколько минут, поэтому время ожидания страницы истекает. Итак, я думаю, что нам нужно, чтобы кнопка отправки запускала задачу, а затем проводила опрос страницы для получения результатов каждые X секунд, пока она не завершится.

Я пытался понять, как это сделать, и видел популярный пост Фила Хаака "Опасности реализации повторяющихся фоновых задач в ASP.NET". Хотя можно привести достойный аргумент, что эту работу должно выполнять внешнее приложение, а не веб-сервер, в действительности оно не будет использоваться очень часто, админам будет нужен веб-интерфейс, и у нас уже есть рабочая версия код, браузер просто не ждет достаточно долго, чтобы сообщить о завершении.

Я наткнулся на HostingEnvironment.QueueBackgroundWorkItem и подумал, что это может сработать, за исключением того, что текущий HttpContext для него недоступен. Я думаю, что это может помешать API CMS, но я также планировал использовать состояние сеанса для своего флага, чтобы указать, когда задача была завершена.

Я видел страницы, такие как туристические веб-сайты или веб-интерфейс SSRS, отображающие страницу опроса, в то время как она выполняет какую-то длительную обработку. Для этого мне не нужно ничего замысловатого или замысловатого, мне просто нужно избежать тайм-аута. Я на неправильном пути с QueueBackgroundWorkItem? Если нет, как я могу узнать, когда задача завершена?


person xr280xr    schedule 04.01.2016    source источник


Ответы (3)


Вы можете использовать такой инструмент, как HangFire, чтобы запускать и выполнять фоновую задачу на вашем сервере и отслеживать ее. Его можно использовать в сочетании с SignalR (как предложил @Tracker1) для уведомлений на стороне клиента о завершении задач.

person Hernan Guzman    schedule 05.01.2016
comment
Это выглядит как хорошо округленное решение. В этом случае я думаю, что сторонний API - это излишество. - person xr280xr; 07.01.2016

Вы, вероятно, захотите использовать один из следующих...

  • Состояние приложения — для хранения состояния обработки, это всего лишь вариант, если ваше приложение находится на одном сервере, а не в нескольких системах. Вы захотите запустить обработку в другом потоке, который обновляет состояние приложения по завершении, чтобы не блокировать запрос на запуск.
  • SignalR — вы можете использовать сообщение, чтобы запустить процесс и вернуть сообщение по завершении. (снова используйте отдельный поток/пул потоков)

Другие варианты включают системы очереди сообщений, которые позволяют отслеживать, заполнен ли билет, или делать это самостоятельно с помощью базы данных.

person Tracker1    schedule 04.01.2016
comment
Я определенно хочу сохранить совместимость с фермой. Задача специфична для пользователя/сеанса. Я полагаю, что идентификатор сеанса может быть сохранен в состоянии приложения, чтобы решить эту проблему. Мы используем сервер состояния сеанса, поэтому кажется, что предоставление текущего HttpSessionState моему фоновому потоку работает. - person xr280xr; 07.01.2016

Я разрешил зависимости CMS API от проблем с HttpRequest, поэтому мне больше не нужно об этом беспокоиться. В итоге я использовал HostingEnvironment.QueueBackgroundWorkItem и передал ему текущий HttpSessionState. Когда действие фонового потока запускается, оно помещает объект в сеанс, чтобы указать, выполняется ли задача, имеет ли она ошибку или успешно завершена. Между тем, страница использует запросы jQuery AJAX для опроса метода страницы ASP.NET, который считывает этот объект состояния из сеанса. Для простых целей этой страницы администратора это работает хорошо. Поскольку мы используем сервер состояния сеанса, это должно работать и в ферме.

person xr280xr    schedule 07.01.2016