Асинхронные контроллеры в ASP.NET 4 имеют смысл?

Asp.net 2 имеет 12 потоков по умолчанию

Теперь у Asp.Net 4 есть 5000. Нам все еще нужны асинхронные контроллеры?

3 ответа

Решение

Нам все еще нужны асинхронные контроллеры?

Да. Асинхронные контроллеры полезны в ситуациях, когда у вас есть длительные операции, такие как сетевые вызовы, и вы не хотите монополизировать для них рабочие потоки. Тот факт, что по умолчанию существует 5000 рабочих потоков, не означает, что их нужно тратить впустую. Это потому, что вы миллионер, что вы отдаете свои деньги? Нет.

Очевидно, что если вы не используете асинхронные контроллеры правильно, они принесут больше вреда, чем пользы.

MVC 4/Dev11 делает контроллеры Async более привлекательными, чем предыдущие версии. Добавьте к этому WebAPI, упрощая создание веб-сервисов. Начало комментариев Леви, чтобы их не пропустить (под прекрасным ответом @Darin Dimitrov)

Немного расширив ответ Дарина - асинхронные операции ввода-вывода (для которых предназначен AsyncController) работают с использованием IOCP, а не потоков ThreadPool. Это важно, поскольку каждый поток ThreadPool имеет связанный стек 1 МБ (плюс другие накладные расходы), поэтому, если вы используете 5000 потоков ThreadPool, вы автоматически теряете 5 ГБ памяти только из-за накладных расходов! Продолжения IOCP далеко не так велики, поэтому их можно манипулировать большим количеством в любой момент времени. Потоки ThreadPool объединяются и удаляются, когда в них больше нет необходимости, поэтому вы берете удар только для тех потоков, которые в данный момент активны. Но если вы выполняете много параллельной работы с CPU с ThreadPool, вы очень быстро начнете сталкиваться с проблемами памяти. Это как раз одна из причин, по которой команды C# / VB выпустили Async CTP несколько месяцев назад - чтобы попытаться решить эту проблему.

Асинхронизация для веб-службы часто имеет смысл - см. Асинхронные ли вызовы моей базы данных Часть II

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

См. Должны ли мои вызовы базы данных быть асинхронными?

4 или 5000, это не важно, это просто настройка. Вы можете установить 1 миллиард, если хотите, это не сделает ваше приложение более масштабируемым. В итоге ваша машина имеет только 4 ядра (или 8 или 2, но не 5000). Всегда имейте в виду, что одновременно может быть запущено столько потоков, сколько число ядер. Каждый поток, превышающий количество ядер, просто накладные расходы. Это создаст больше переключателей контекста, потребит процессор и займет больше памяти.

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

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

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