2013-09-06 2 views
4

Нужно ли что-либо делать, чтобы сделать все запросы асинхронными или они автоматически обрабатываются таким образом?Web API 2 - все запросы REST асинхронны?

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

Обновление: (У меня плохая привычка не объяснять полностью - извините) Вот моя забота. Клиентский браузер делает запрос REST на мой сервер http://data.domain/com/employee_database/?query=state:Colorado. Это подходит к соответствующему методу в контроллере. Этот метод запрашивает базу данных и возвращает объект, который затем превращается в структуру JSON и возвращается в вызывающее приложение.

Теперь предположим, что 10 000 клиентов выполняют аналогичный запрос на один и тот же сервер. Итак, у меня сразу 10 000 запросов. Будет ли мой метод контроллера вызываться одновременно в 10 000 отдельных потоков? Или должен ли первый запрос вернуться до вызова второго запроса?

Я не спрашиваю о коде в моем методе обработчика, имеющем асинхронные компоненты. Для моего случая запрос становится единственным SQL-запросом, поэтому код не имеет ничего, что можно обрабатывать асинхронно. И пока я не получу запрошенные данные, я не могу вернуться из метода.

+1

Если вы имеете в виду асинхронные действия, то следует использовать 'async':' public async Task > Get() {...} ' – Vladimir

+0

@VladimirFrolov Почему веб-api не создает поток каждый раз, когда он начинает обслуживать пользователя? Таким образом, не имеет значения, спит ли в действии, как это было бы в собственной нити. – Ciantic

+0

@ Давид Не могли бы вы рассказать о своих выводах. Ответы ниже не отвечают на ваш конкретный вопрос. –

ответ

1

Чтобы быть честным, ваш вопрос не очень ясен. Если вы делаете HTTP GET с использованием HttpClient, скажем, метод GetAsync, запрос уволен, и вы можете делать все, что хотите, в своем потоке, пока не получите ответ. Таким образом, этот запрос является асинхронным. Если вы спрашиваете о стороне сервера, которая обрабатывает этот запрос (при условии, что это ASP.NET Web API), то асинхронно или не зависит от того, как вы реализовали свой веб-API. Если ваш метод действия выполняет три вещи, скажем, 1, 2 и 3 один за другим синхронно в режиме блокировки, тот же поток отправляет службе запрос. С другой стороны, скажем, что № 2 выше - это вызов веб-службы, и это HTTP-вызов. Теперь, если вы используете HttpClient и вы выполняете асинхронный вызов, вы можете попасть в ситуацию, когда один запрос обслуживается более чем одним потоком. Чтобы это произошло, вы должны были сделать HTTP-вызов из вашего метода действий асинхронно и использовать ключевое слово async. В этом случае, когда вы вызываете await в метод действия, выполняется действие вашего действия, и поток, обслуживающий ваш запрос, может обслуживать какой-либо другой запрос, и в конечном итоге, когда ответ будет доступен, тот же или какой-либо другой поток будет продолжен, откуда был остановлен ранее. Долгий скучный ответ, возможно, но трудно объяснить просто словами, набрав, я думаю. Надеюсь, вы получите некоторую ясность.

UPDATE: Ваш метод действия будет выполнять параллельно в 10000 нитей (в идеале). Почему я говорю в идеале, потому что пул потоков CLR, имеющий 10 000 потоков, не типичен и, вероятно, непрактичен. Существуют физические ограничения, а также ограничения, налагаемые структурой, но, я думаю, ответ на ваш вопрос заключается в том, что запросы будут обслуживаться параллельно. Правильный термин здесь будет «параллельным», но не «асинхронным».

+0

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

+0

Спасибо. Мое тестирование показало, что, но лучше иметь авторитетный ответ, поскольку мой тест мог быть отключен. И я в порядке, если для этого примера это 1000 параллельных запросов, а остальные - в очереди. Базовая база данных будет ударять по параллельным лимитам вокруг, и я тоже думаю. –

0

Независимо от того, является ли оно синхронизацией или асинхронным, это ваш выбор. Вы выбираете, чтобы написать свое действие. Если вы вернете задачу, а также используете async IO под капотом, это будет асинхронно. В других случаях это синхронно.

Не стесняйтесь ударить async о своем действии и использовать Task.Run. Это асинхронная синхронизация (известный анти-шаблон). Он должен быть действительно асинхронным вплоть до ядра ОС.

Никакой каркас не может синхронизировать IO автоматически асинхронно, так что это не может произойти под капотом. Async IO основан на обратном вызове, что является серьезным изменением в модели программирования.

Это не ответит на то, что вы должно сделать конечно. Это будет новый вопрос.

+0

Извините, но я не думаю, что это отвечает на мой вопрос. В случае веб-API я думаю, что асинхронный процесс должен произойти в структуре веб-API, так как я должен вернуть данные, запрошенные в вызове. Я что-то упускаю? –

+0

Каков ваш вопрос? «Нужно ли мне что-либо делать, чтобы сделать все запросы асинхронными или они автоматически обрабатываются таким образом?» => Да, вам нужно быть асинхронным в своем собственном действии. Структура не автоматически async. Он * может * вести себя асинхронно, если вы тоже. Он отражает то, что вы делаете; «так как я должен вернуть данные, запрошенные в вызове»: вы можете либо вернуть его синхронно (без async и без использования Task). Тогда действие будет синхронным. Вы также можете вернуть задачу, которая сделает действие асинхронным. С помощью задачи вам не нужно немедленно возвращать результат. – usr

+0

«Будет ли мой метод контроллера вызываться одновременно в 10 000 отдельных потоков?»: При синхронном действии он будет вызываться во многих потоках (не точно 10k, но многих). При асинхронном действии количество потоков будет очень низким (около количества процессоров), но количество одновременно активных действий по-прежнему будет высоким (этот предел можно настроить). Все async - это разблокировать запросы, так что у вас их меньше. Он не меняет (прямо), сколько действий обрабатывается в одно и то же время. «Или должен ли первый запрос вернуться до вызова второго запроса?»: Это никогда не бывает. – usr

0

По умолчанию для REST не существует async. запрос обрабатывается синхронно. Тем не менее, ваш веб-сервер (IIS) имеет несколько параметров максимальных потоков, которые могут работать в одно и то же время, и он поддерживает очередь полученного запроса. Таким образом, запрос отправляется в очередь, и если поток доступен, он запускается иначе, запрос ожидает в очереди IIS до тех пор, пока не будет доступен поток

1

Я думаю, что вы должны использовать async IO/операции, такие как вызовы базы данных в ваш случай. Да в Web Api, каждый запрос имеет свой собственный поток, но потоки могут закончиться, если есть много последовательных запросов. Также потоки используют память, поэтому, если ваш api попадает в слишком много запросов, он может оказывать давление на вашу систему.

Преимущество использования асинхронной синхронизации заключается в том, что вы разумно используете свои системные ресурсы. Вместо блокировки потока, когда он ожидает завершения вызова базы данных в реализации синхронизации, async освободит поток, чтобы обрабатывать больше запросов или назначать ему то, что требуется процессу для потока. Как только вызов IO (базы данных) завершится, другой поток возьмет его оттуда и продолжит реализацию. Async также сделает ваш api быстрее, если ваши операции ввода-вывода будут занимать больше времени.