Обработка данных на основе очереди в веб-приложении ASP.NET MVC

Как я могу реализовать очереди фоновой обработки в моем веб-приложении ASP.NET MVC? В то время как большинство изменений данных, обновления и т.д. Должны быть сразу видны, есть другие обновления, которые не требуют обработки в реальном времени, которые я бы хотел передать в фоновый процесс с более низким приоритетом, который позаботится об этом в своем собственном темпе.

В качестве примера возьмите систему награды StackOverflow. Обычно вы можете предпринять конкретные действия, которые принесут вам значок, но фактическая "награда" произойдет позже (обычно между 10 минутами и несколькими часами позже). Я предполагаю, что это делается с помощью отдельного фонового процесса, так как это не критично для SO-обработки для немедленного получения значков при получении.

Итак, я пытаюсь создать какую-то систему очередей, в которой я мог бы заполнять задачи (скажем, что-либо, реализующее интерфейс ITask, который будет иметь метод Process()), который в конечном итоге будет выполняться отдельным процессом.

Как я могу реализовать такую ​​систему? Идеи/подсказка/пример кода?

Спасибо!

Ответ 1

Службы Windows и MSMQ для связи с ними (если вам даже нужно).

- Изменить

Чтобы немного развернуть.

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

Возможно, вы захотите взаимодействовать с ними с точки зрения администратора, поэтому у вас может быть MSMQ, в котором они прослушивают команды администратора. В зависимости от вашей реализации вам может потребоваться перезапустить их по какой-либо причине или, возможно, просто "заставить" выполнить все, что они хотят сделать.

Итак, для этого вы будете использовать приватную очередь MSMQ (пространство имен 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

Ответ 2

У Джеффа отличная статья, показывающая, как он достиг этого изначально для Qaru в http://blog.stackoverflow.com/2008/07/easy-background-tasks-in-aspnet/

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

Ответ 3

Просто нашел этот вопрос при поиске фонового процесса в 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 HowToRunBackgroundTasksInASPNET