Фоновая обработка на основе очередей в веб-приложении ASP.NET MVC
Как реализовать очереди фоновой обработки в моем веб-приложении ASP.NET MVC? Хотя большинство изменений данных, обновлений и т. Д. Должны быть видны немедленно, есть и другие обновления, которые не требуют обработки в реальном времени, и я хотел бы передать их фоновому процессу с более низким приоритетом, который позаботится об этом в своем собственном темпе.,
В качестве примера возьмем систему награждения значками Stackru. Обычно вы можете предпринять определенное действие, которое присудит вам значок, но фактическая "награда" происходит позже (обычно от 10 минут до пары часов спустя). Я предполагаю, что это делается с помощью отдельного фонового процесса, так как для работы SO не важно, чтобы награждать значки сразу же после их получения.
Итак, я пытаюсь создать какую-то систему очередей, в которой я мог бы заполнять задачи (скажем, все, что реализует интерфейс ITask, который будет иметь метод Process()), который в итоге будет выполняться отдельным процессом.
Как бы я занялся внедрением такой системы? Идеи / Подсказка / Пример кода?
Спасибо!
3 ответа
Службы Windows и MSMQ для связи с ними (если вам даже нужно).
-- Редактировать
Чтобы немного расширить.
Вы создадите несколько сервисов, в зависимости от того, что вы хотите сделать, и сделаете так, чтобы все они выполняли бесконечный поток различных уровней ожидания, чтобы делать то, что вы хотите. Затем они обновят базу данных соответствующим образом, и вам не придется ничего делать на стороне клиента.
Вы можете захотеть взаимодействовать с ними с точки зрения администратора, поэтому у вас может быть MSMQ, на котором они слушают команды администратора. В зависимости от вашей реализации вам может понадобиться перезапустить их по какой-то причине или, возможно, просто "заставить" запустить то, что они хотят сделать.
Таким образом, вы будете использовать MSMQ Private Queue для этого (пространство имен System.Messaging). Одно из главных замечаний, касающихся MSMQ, это то, что сообщение должно быть < 4meg. Поэтому, если вы намереваетесь отправить графы больших объектов, сначала сериализуйте файл и просто отправьте имя файла.
MSMQ довольно красивый. Вы можете отправлять на основе "Идентификатора корреляции", если вам нужно, но по какой-то забавной причине идентификатор корреляции должен иметь вид:
{guid}\1
Все остальное не работает (по крайней мере, в версии 2.0 фреймворка код мог измениться).
-- Редактировать
Пример по запросу:
using System.Messaging;
...
MessageQueue queue = new MessageQueue(".\\Private$\\yourqueue");
queue.Formatter = new BinaryMessageFormatter();
Message m = new Message();
m.Body = "your serialisable object or just plain string";
queue.Send(m);
// on the other side
MessageQueue queue = new MessageQueue(".\\Private$\\yourqueue");
queue.Formatter = new BinaryMessageFormatter();
Message m = queue.Receive();
string s = m.Body as string;
// s contains that string now
У Джеффа есть отличный пост, показывающий, как он достиг этого изначально для переполнения стека, по адресу http://blog.stackru.com/2008/07/easy-background-tasks-in-aspnet/
Хотя это может быть не так надежно, как услуга, если это вариант для вас, в прошлом он хорошо служил мне для несущественных задач, и я работал в среде виртуального хостинга.
Просто нашел этот вопрос при поиске фонового процесса в ASP.NET MVC. (Доступно после.NET 4.5.2)
public ActionResult InitiateLongRunningProcess(Emails emails)
{
if (ModelState.IsValid)
{
HostingEnvironment.QueueBackgroundWorkItem(ct => LongRunningProcessAsync(emails.Email));
return RedirectToAction("Index", "Home");
}
return View(user);
}
Примечание. Лично я не буду использовать веб-сервер для запуска фоновых задач. Также не изобретайте велосипед, я очень рекомендую использовать Hangfire.
Прочитайте эту замечательную статью от Hanselman http://www.hanselman.com/blog/HowToRunBackgroundTasksInASPNET.aspx