Как реализовать шаблон рассеяния в веб-приложении ASP.NET?

Предположим, запрос ASP.NET WebAPI поступает в метод контроллера.

Предположим, что запрос представляет собой "событие", которое необходимо обработать. С событием связано несколько операций, которые должны выполняться параллельно. Например, каждой операции может потребоваться вызвать конкретную конечную точку REST на других серверах, которые являются операциями, связанными с вводом-выводом, которые должны начаться как можно скорее и не должны ждать, пока одна из них вернется, прежде чем начинать следующую.

Каков наиболее правильный / эффективный способ реализации этого шаблона?

Я читал, что использование Task.Run - плохая идея, потому что он просто захватывает дополнительные потоки ThreadPool, оставляя основной поток запросов незанятым / заблокированным. Хотя это имеет смысл, если бы я выполнял одну задачу, я не уверен, что этот совет применим в этом случае.

Например, если событие имеет 4 операции, которые необходимо было выполнить (каждая из которых имела несколько собственных вызовов, связанных с вводом / выводом), я бы вызвал Task.Run в цикле 4 раза, чтобы инициализировать каждую операцию, а затем дождался выполнения результирующих задач с Task.WaitAll,

В1: Будет ли основной поток запроса возвращен в ThreadPool для использования другим запросом в ожидании возврата Task.WaitAll, или он просто запустит основной поток, оставив его бездействующим до завершения Task.WaitAll?

Q2: Если он захватывает основной поток, это можно решить, пометив метод контроллера с помощью async ключевое слово, и используя await Task.WhenAll вместо звонка? Я предполагал, что это вернет основной поток в пул во время ожидания, что позволит использовать его для других запросов или операций с событиями.

Q3: с Task.Run ставит в очередь рабочий элемент, который может быть заблокирован при вызове, связанном с вводом-выводом, улучшит производительность, если все операции будут реализованы с async и использовал await вызывает на основе задач асинхронных методов ввода-вывода?

Что касается всего подхода к использованию Task.Run для операций события, то цель состоит в том, чтобы как можно скорее запустить все связанные с операциями ввода-вывода вызовы. Я полагаю, если (как в Q3) все операции были async методы, я мог бы просто запустить их все в главном потоке запросов в цикле, но я не уверен, что это будет лучше, чем запускать их с отдельными вызовами Task.Run. Может быть, есть совершенно другой подход, который я не знаю.

0 ответов

Другие вопросы по тегам