Я знаю, что существует множество API, которые делают это, но я также знаю, что среда хостинга (будучи ASP.NET) накладывает ограничения на то, что вы можете надежно делать в отдельном потоке.
Я могу быть совершенно неправ, поэтому, пожалуйста, поправьте меня, если я ошибаюсь, однако это то, что я думаю, что знаю.
- Время ожидания запроса обычно истекает через 120 секунд (это настраивается), но в конечном итоге среда выполнения ASP.NET уничтожит запрос, выполнение которого занимает слишком много времени.
- Среда хостинга, обычно IIS, использует повторное использование процессов и может в любой момент принять решение о повторном использовании вашего приложения. Когда это происходит, все потоки прерываются и приложение перезапускается. Однако я не уверен, насколько он агрессивен, было бы глупо предполагать, что он прервет обычный текущий HTTP-запрос, но я ожидаю, что он прервет поток, потому что он ничего не знает о блоке работы потока.
Если бы вам нужно было создать модель программирования, которая легко, надежно и теоретически ставит длительную задачу, которая должна выполняться в течение нескольких дней, как бы вы выполнили это из приложения ASP.NET?
Вот что я думаю по этому поводу:
Я долго думал о размещении службы WCF в службе win32. И поговорить с сервисом через WCF. Однако это не очень практично, потому что единственная причина, по которой я бы решил это сделать, — это отправлять задачи (единицы работы) из нескольких разных веб-приложений. Затем я в конечном итоге попросил бы службу обновить статус и действовал соответственно. Меня больше всего беспокоит то, что это НЕ было бы особенно хорошим опытом, если бы мне приходилось развертывать каждую задачу в службе, чтобы она могла выполнять некоторые инструкции. Есть также проблема с вводом данных: как бы я снабжал эту службу данными, если бы у меня был большой набор данных и мне нужно было его пережевывать?
Что я обычно делаю сейчас, так это
SELECT TOP 10 *
FROM WorkItem WITH (ROWLOCK, UPDLOCK, READPAST)
WHERE WorkCompleted IS NULL
Это позволяет мне использовать базу данных SQL Server в качестве рабочей очереди и периодически опрашивать базу данных с помощью этого запроса для работы. Если рабочий элемент выполнен успешно, я отмечаю его как выполненный и продолжаю, пока больше нечего будет делать. Что мне не нравится, так это то, что теоретически меня могут прервать в любой момент, и если я нахожусь между успехом и отмечаю его как выполненный, я могу в конечном итоге обработать один и тот же рабочий элемент дважды. Я могу быть немного параноиком, и все может быть хорошо, но, как я понимаю, нет никакой гарантии, что этого не произойдет...
Я знаю, что подобные вопросы были на SO раньше, но на самом деле нет ответов с окончательным ответом. Это очень распространенная вещь, но среда размещения ASP.NET плохо приспособлена для выполнения длительной работы.
Пожалуйста, поделитесь своими мыслями.