Использовать асинхронный метод на сервисном уровне из MVC 5?

1

Я разрабатываю приложение 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-mvc
async-await
asynchronous

1 ответ

3
Лучший ответ

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

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

Лучшим решением является настройка надежной очереди (например, Azure Queue) с отдельным бэкэндом (таким как Azure WebJob), который обрабатывает эту очередь надежным способом. Это правильное решение, но многие люди просто этого не сделают, потому что это сложно.

Если в вашем решении есть база данных SQL Server или Redis, подумайте о Hangfire. Hangfire использует базу данных как надежную очередь и выполняет свою поддержку вместе с вашим приложением ASP.NET.

Если вы хотите жить опасно, по крайней мере, вы должны использовать HostingEnvironment.QueueBackgroundWorkItem, который будет информировать ASP.NET о работе вашего приложения за пределами запроса.

Что-то не так с подходом?

Да; _myService.TestAsync пытается возобновить запрос в запросе, который уже завершен.

  • 0
    Я кратко рассмотрел Hangfire - я использую MongoDB для BackEnd DB, хотя не уверен, будет ли он работать с ним.
  • 0
    Без добавления сложности очереди и отсутствия на .NET 4.5.2 - приложение 4.5 - есть ли способ, которым я могу вызвать этот уровень обслуживания и создать новый поток для выполнения работы - так как не нужно возвращать что-то для пользователя - я просто хочу, чтобы новый поток выполнял работу и сохранял данные из веб-службы в БД
Показать ещё 2 комментария

Ещё вопросы

Сообщество Overcoder
Наверх
Меню