Я разрабатываю приложение ASP.NET MVC 5. Я читал здесь несколько вопросов, которые предлагают не использовать тип поведения, который я хочу.
Высокий уровень того, чего я хочу достичь -
MVC Controller - вызывает метод на уровне сервиса, а затем переходит к следующей строке кода в контроллере, так как не нужно ничего возвращать.
Метод на уровне обслуживания. Я хочу вызвать некоторую внешнюю веб-службу, у которой есть методы Async, поэтому я хочу, чтобы они были выключены, а затем записывали данные в БД при их возврате.
Что-то вроде этого достижимо или не лучший подход?
В Dummy это и проверить принцип у меня есть следующие на контроллере:
[AcceptVerbs(HttpVerbs.Post)]
public ActionResult TestAsync()
{
_myService.TestAsync();
return RedirectToAction("Summary");
}
В _myService метод выглядит следующим образом:
public async Task TestAsync()
{
await Task.Delay(10000);
var test = "Testing";
_testRepository.Add(test);
}
Я надеялся, что этот метод TestAsync будет ждать 10 секунд, а затем я могу проверить БД, и будет добавлено значение Тестирование. Однако это не работает. В пользовательском интерфейсе после нажатия кнопки страница переходит к "Сводному просмотру" и "Ожидание". Точка останова. Делая точку доступа, но следующие строки никогда не выполняются. Что-то не так с подходом? Если метод TestAsync просто выглядит примерно так:
public void TestAsync()
{
//Call another private async method here in the class that does the task delay
//which would be similar to calling the actual Async External Web Service methods
var test = "Testing";
_testRepository.Add(test);
}
Я читал здесь несколько вопросов, которые предлагают не использовать тип поведения, который я хочу.
Это потому, что это опасно. ASP.NET решает безопасно выгружать ваш AppDomain, когда активных запросов нет, поэтому, если вы вернетесь из действия вашего контроллера, пока у вас еще есть работа, ASP.NET не будет знать об этой работе.
Лучшим решением является настройка надежной очереди (например, Azure Queue) с отдельным бэкэндом (таким как Azure WebJob), который обрабатывает эту очередь надежным способом. Это правильное решение, но многие люди просто этого не сделают, потому что это сложно.
Если в вашем решении есть база данных SQL Server или Redis, подумайте о Hangfire. Hangfire использует базу данных как надежную очередь и выполняет свою поддержку вместе с вашим приложением ASP.NET.
Если вы хотите жить опасно, по крайней мере, вы должны использовать HostingEnvironment.QueueBackgroundWorkItem
, который будет информировать ASP.NET о работе вашего приложения за пределами запроса.
Что-то не так с подходом?
Да; _myService.TestAsync
пытается возобновить запрос в запросе, который уже завершен.