Когда я должен использовать асинхронные контроллеры в ASP.NET MVC?
У меня есть некоторые проблемы с использованием асинхронных действий в ASP.NET MVC. Когда это улучшает производительность моих приложений, и когда это не?
- хорошо ли использовать асинхронное действие везде в ASP.NET MVC?
- Что касается ожидаемых методов: должен ли я использовать ключевые слова async/await, когда я хочу запросить базу данных (через EF/NHibernate/other ORM)?
- сколько раз я могу использовать ключевые слова await для асинхронного запроса базы данных в один метод одиночного действия?
6 ответов
асинхронные действий методы полезны, когда действие должно выполнять несколько независимых длительных операций.
типичное использование для класса AsyncController-это длительный веб вызов службы.
должны ли мои вызовы базы данных быть асинхронными ?
пул потоков IIS часто может обрабатывать гораздо больше одновременных запросов блокировки, чем сервер базы данных. Если база данных является узким местом, асинхронные вызовы не будут скорость ответа базы данных. Без механизма регулирования эффективная отправка большего объема работы на перегруженный сервер баз данных с помощью асинхронных вызовов просто переносит большую часть нагрузки на базу данных. Если ваша БД является узким местом, асинхронные вызовы не будут волшебной пулей.
вы должны посмотреть 1 и 2 ссылки
производные от @PanagiotisKanavos комментарии:
кроме того, асинхронность не означает параллельность. Асинхронное выполнение освобождает ценный поток threadpool от блокировки для внешнего ресурса, для никаких сложностей или затрат. Это означает, что одна и та же машина IIS может обрабатывайте больше параллельных запросов, а не то, что он будет работать быстрее.
вы также должны учитывать, что блокирование вызовов начинается с CPU-интенсивный spinwait. Во время стрессовых ситуаций блокировка вызовов будет результат в эскалации задержек и утилизации пула приложений. Асинхронный вызов просто избегайте этого
вы можете найти меня MSDN статья на эту тему полезна; я занял много места в этой статье, описывающей когда вы должны использовать async
ВКЛ ASP.NET не просто как использовать async
ВКЛ ASP.NET.
у меня есть некоторые проблемы с использованием асинхронных действий в ASP.NET MVC. Когда это улучшает производительность моих приложений, а когда - нет.
во-первых, понять, что async
/await
- все о освобождая нити. В приложениях GUI в основном речь идет о освобождение потока GUI таким образом, пользовательский опыт лучше. На серверных приложениях (включая ASP.NET MVC), это в основном о освобождение потока запроса таким образом, сервер может масштабироваться.
в частности,не так:
- Сделайте ваши индивидуальные запросы быстрее. На самом деле, они будут завершаться (только немного) медленнее.
- вернуться к вызывающий абонент / браузер, когда вы нажмете
await
.await
только "выходы" к ASP.NET пул потоков, а не браузер.
первый вопрос - Хорошо ли использовать асинхронное действие везде в ASP.NET MVC?
Я бы сказал, что хорошо использовать его везде, где вы делаете I / O. Это не обязательно может быть выгодно, хотя (см. ниже).
однако,плохо использовать его для методов, связанных с CPU. Иногда devs думаю, они могут получить преимущества async
просто позвонив по номеру Task.Run
в их контроллерах, и это ужасная идея. Потому что этот код в конечном итоге освобождает поток запроса, занимая другой поток, поэтому нет никакой выгоды вообще (и на самом деле они берут штраф за дополнительные переключатели потоков)!
должен ли я использовать ключевые слова async/await, когда я хочу запросить базу данных (через EF/NHibernate/other ORM)?
вы можете использовать любые ожидаемые методы у вас есть в наличии. Сейчас большинство крупных игроков поддерживают async
, но есть несколько, которые этого не делают. Если ваш ORM не поддерживает async
, тогда не пытайтесь завернуть его в Task.Run
или что-то в этом роде (см. выше).
обратите внимание, что я сказал " Вы мог бы использовать". Если ты говоришь о ASP.NET MVC с одним бэкэндом базы данных, тогда вы (почти наверняка) не получите никакого преимущества масштабируемости от async
. Это связано с тем, что IIS может обрабатывать гораздо более параллельные запросы, чем один экземпляр SQL server (или других классических СУБД). Однако, если ваш бэкэнд более современный-кластер SQL server, Azure SQL, NoSQL и т. д. - и ваш бэкэнд может масштабироваться, а узким местом масштабируемости является IIS,затем вы можете получить преимущество масштабируемости от async
.
третий вопрос-сколько раз я могу использовать ключевые слова await для асинхронного запроса базы данных в одном методе действия?
как много, как вы как. Однако обратите внимание, что многие ORM имеют правило одной операции на соединение. В частности, EF разрешает только одну операцию на DbContext; это верно, является ли операция синхронной или асинхронной.
кроме того, имейте в виду масштабируемость серверной части снова. Если вы нажмете один экземпляр SQL Server, и ваши IIS уже способны поддерживать SQLServer на полную мощность, то удвоение или утроение давления на SQLServer не поможет вам в все.
хорошо ли использовать асинхронное действие везде в ASP.NET MVC?
как обычно в программировании, это зависит. Всегда есть компромисс, когда идешь по определенному пути.
async-await
светит в местах, где вы знаете, что вы будете получать параллельные запросы к вашей службе, и вы хотите иметь возможность масштабирование хорошо. Как это async-await
помощь в масштабировании? В том, что при вызове асинхронного вызова ввода-вывода синхронно, например, сетевой вызов или попадание в базу данных, текущий поток, который отвечает за выполнение, блокируется в ожидании завершения запроса. Когда вы используете async-await
, вы включаете фреймворк для создания государственной машины для вас, которая гарантирует, что после завершения вызова ввода-вывода ваш метод продолжает выполняться с того места, где он остановился.
следует отметить, что эта государственная машина имеет тонкие накладные расходы. Создание асинхронного метода не делает его выполнить быстрее, и это является важным фактором для понимания и заблуждения многих людей.
еще одна вещь, которую следует учитывать при использовании async-await
Это факт, что это асинхронный полностью, что означает, что вы увидите, как асинхронно проникает весь ваш стек вызовов, сверху донизу. Это означает, что если вы хотите предоставить синхронные API, вы часто будете дублировать определенный объем кода, как асинхронные и синхронизация не очень хорошо перемешать.
должен ли я использовать ключевые слова async/await, когда я хочу запросить базу данных (через EF/NHibernate / other ORM)?
если вы решите пойти по пути использования асинхронных вызовов ввода-вывода, то да,async-await
будет хорошим выбором, так как все больше и больше современных поставщиков баз данных предоставляют асинхронный метод, реализующий TAP (асинхронный шаблон задачи).
сколько раз я могу использовать await ключевые слова для запроса базы данных асинхронно в одном методе действия?
столько, сколько вы хотите, при условии, что вы будете следовать правилам, изложенным поставщиком базы данных. Количество асинхронных вызовов не ограничено. Если у вас есть запросы, которые независимы друг от друга и могут быть сделаны одновременно, вы можете создать новую задачу для каждого и использовать await Task.WhenAll
ждать как полный.
async
действия помогают лучше всего, когда действия выполняют некоторые операции ввода-вывода в БД или некоторые сетевые вызовы, где поток, обрабатывающий запрос, будет остановлен, прежде чем он получит ответ от БД или сетевого вызова, который вы только что вызвали. Лучше всего использовать await с ними, и это действительно улучшит отзывчивость вашего приложения (потому что меньше потоков ввода / вывода ASP будет остановлено во время ожидания БД или любой другой операции). Во всех моих приложениях всякий раз, когда многие вызовы DB очень необходимы, я всегда обертывал их в awaiatable метод и вызывал это с await
ключевое слово.
мои 5 копеек:
- использовать
async/await
если и только если вы выполняете операцию ввода-вывода, например DB или external service webservice. - всегда предпочитайте асинхронные вызовы БД.
- каждый раз, когда вы запрос к БД.
P. S. есть исключительные случаи для пункта 1, но вы должны иметь хорошее понимание асинхронности внутренностей для этого.
в качестве дополнительного преимущества вы можете делать несколько вызовов ввода-вывода параллельно, если это необходимо:
Task task1 = FooAsync(); // launch it, but don't wait for result
Task task2 = BarAsync(); // launch bar; now both foo and bar are running
await Task.WhenAll(task1, task2); // this is better in regard to exception handling
// use task1.Result, task2.Result
Как вы знаете, MVC поддерживает асинхронные контроллеры,и вы должны воспользоваться этим. Если ваш контроллер выполняет длительную операцию (это может быть дисковый ввод-вывод или сетевой вызов другой удаленной службы), если запрос обрабатывается синхронно, поток IIS занят все время. В результате поток просто ждет завершения длительной операции. Его можно более лучше использовать путем служение других запросов пока деятельность спрошенная внутри сперва под достижения. Это поможет обслуживать больше одновременных запросов. Ваш веб-сервис будет очень масштабируемым и не будет легко работать в проблема C10k. Рекомендуется использовать async / await для запросов БД. и да, вы можете использовать их столько раз, сколько вы сочтете нужным.
посмотреть здесь для отличные советы.