.net 4.5, asp.net mvc: как лучше всего запустить длительный процесс (1-2 минуты) из приложения ASP.NET, при этом его следует запускать в однопоточной среде, я имею в виду, что процесс инициируется для только один пользователь за раз, выполнение для всех других пользователей должно ждать, пока не будет выполнено текущее выполнение? Сценарий следующий: пользователь нажимает кнопку, которая запускает какие-то длительные вычисления, ответ http возвращается пользователю немедленно, затем пользователь должен запросить статус вычислений с помощью отдельного запроса вручную. Прерывание http-сессии Asp.net не должно приводить к завершению процесса, оно должно продолжаться. Процесс может выполняться на том же или отдельном сервере.
Как запустить длительный процесс асинхронно под asp.net?
Ответы (4)
Я бы предложил использовать такой продукт, как NServiceBus, чтобы разгрузить обработку и запустить ее в однопоточном режиме. Преимущество этого заключается в том, что все запросы будут обрабатываться по порядку, и обработка может быть выгружена с веб-сервера, поскольку вы действительно не хотите, чтобы на веб-сервере происходили длительные процессы.
Я покажу вам, как выполнить эту задачу с помощью http://hangfire.io — невероятно простого способа -забудьте об отложенных и повторяющихся задачах внутри приложений ASP.NET. Служба Windows не требуется.
Сначала установите пакет через NuGet. Если у вас возникли проблемы, обратитесь к руководству по быстрому запуску на официальном документация.
PM> Install-Package Hangfire
Откройте свой класс запуска OWIN и добавьте следующие строки:
public void Configure(IAppBuilder app)
{
GlobalConfiguration.Configuration.UseSqlServerStorage("connection_string");
app.UseHangfireDashboard();
app.UseHangfireServer();
}
Затем напишите метод, который будет выполнять длительную работу (я применил атрибут для выполнения только одного метода за раз):
[DisableConcurrentExecution]
public void LongRunning()
{
// Some processing stuff
}
А затем вызовите метод в фоновом режиме, чтобы немедленно ответить пользователю:
public ActionResult Perform()
{
BackgroundJob.Enqueue(() => LongRunning());
return View();
}
Если вы хотите уведомить пользователя о завершении задания, рассмотрите возможность использования SignalR и добавьте метод LongRunning
соответственно.
.Net 4.5.2 добавляет QueueBackgroundWorkItem которые вы можете использовать для планирования задачи. Если вы не контролируете сервер (когда он перезагружается), 90-секундная задержка закрытия appPool по умолчанию не будет работать (если только вы не обнаружите, что задача не завершена, и запустите ее на другом сервере). Дополнительные сведения см. в разделе "QueueBackgroundWorkItem для надежного планирования и запуска фоновых процессов в ASP.NET"
Если вы управляете сервером и нуждаетесь в большей простоте, чем полная структура, такая как Hangfire, вы можете создать консольное приложение (.exe) и сделать что угодно..., тогда вы можете вызвать .exe с помощью Process.Start, вы может вызвать .exe из SQL Server, службу и т. д.