Запуск ожидаемого задания асинхронно в asp.net - PullRequest
1 голос
/ 07 января 2020

У меня в контроллере следующее действие:

[HttpPost("run")]
public Task<object> Run([FromBody] ResearchRequest researchRequest)
{
   researchService.RunAsync(researchRequest);
   return new{ queued = true   };
}

Контроллер должен обрабатывать задачу, которая занимает несколько минут.
Это правильный способ разблокировки researchService.RunAsync для выполнения своей работы ?

Или есть лучший подход.

Спасибо

Ответы [ 2 ]

0 голосов
/ 07 января 2020

Вы можете сделать это , если RunAsync делает запросы ввода / вывода , но вы не вернете Task:

[HttpPost("run")]
public object Run([FromBody] ResearchRequest researchRequest)
{
   researchService.RunAsync(researchRequest);
   return new{ queued = true   };
}

Это запустит RunAsync в том же потоке, как и любой другой метод. В первом await в RunAsync, который действует на неполное Task, RunAsync вернет свой собственный неполный Task, после чего управление вернется к вашему действию Run, и ваш object будет возвращен , Вы не будете ждать операции ввода-вывода, которую RunAsync сделает.

Если RunAsync занимает много времени из-за вычислений ЦП (не ввода-вывода), то это ничего не изменит для вас, потому что, помните, он начинает работать в том же потоке. Вам придется запустить его в другом потоке, что можно сделать, используя Task.Run:

[HttpPost("run")]
public Task<object> Run([FromBody] ResearchRequest researchRequest)
{
   Task.Run(() => researchService.RunAsync(researchRequest));
   return new{ queued = true   };
}

Но!

В обоих случаях ASP. NET не будет знать, что RunAsync работает в фоновом режиме. Если пул приложений IIS по какой-либо причине будет закрыт или переработан, это задание будет завершено на полпути. Обратите внимание, что по умолчанию IIS настроен на отключение пула приложений после 20 минут отсутствия поступающих HTTP-запросов.

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

0 голосов
/ 07 января 2020

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

, чтобы пользовательский интерфейс мог перейти от этой страницы и вернуться, чтобы увидеть, что процесс запущен

...