Позвольте мне сначала понять суть вашего вопроса, путаница связана с , где использовать Async в полной цепочке вызовов, а где нет и , как оценить влияние использования на производительность , так как это может привести к созданию большего количества потоков. Если синопсис выходит за рамки этого, добавьте детали к комментариям, я пока попытаюсь ответить на них.
Давайте разделим и разберем каждого из них по одному.
Где использовать Async в цепочке вызовов, а где нет?
- Здесь, когда вы используете Entity Framework для доступа к базе данных, я могу с уверенностью предположить, что вы используете асинхронную обработку на основе ввода-вывода, которая является наиболее заметным вариантом использования для асинхронной обработки в разных языках и средах, примеры использования для асинхронной обработки на основе ЦП: относительно ограничен (объясню их тоже)
- Async - это функция масштабируемости, особенно для обработки ввода-вывода, а не для повышения производительности. Проще говоря, с помощью асинхронной обработки вы можете гарантировать, что размещенный сервер может обслуживать во много раз больше вызовов для обработки ввода-вывода, поскольку вызовы не блокируются и они просто передаются вручную. через запрос обработки по сети, в то время как поток процесса возвращается в пул, готовый обработать другой запрос, завершая передачу процесса за несколько миллисекунд
- Когда обработка завершена, программный поток должен просто принять их и передать обратно клиенту, опять же, через несколько миллисекунд, в основном это около <1 мс, если это чистый проход без логического вызова IO </li>
Какие преимущества
- Представьте, что вместо этого вы делаете синхронный вызов ввода-вывода в базу данных, где каждый задействованный поток будет просто ждать получения результата, который может пройти через несколько секунд, влияние будет крайне отрицательным, в целом, в зависимости от размера пула потоков, вы можете сервер Максимум 25 - 50 запросов, и они тоже ответят о количестве ядер, доступных для обработки, будут постоянно тратить ресурсы впустую, пока они простаивают и ожидают ответа
- Если вы делаете синхронный вызов, то невозможно выполнить более 1000 запросов в одной и той же настройке, и я очень консервативен. Async может оказать огромное влияние на масштабируемость, тогда как для облегченных вызовов он может легко обслуживать миллионы запросов из одного размещенного процесса
После фона, где использовать Async в полной цепочке
- Везде , выполнимо от начала до конца, от точки входа до фактической точки выхода, выполняющей вызов IO, поскольку это фактический вызов, освобождающий поток пула, поскольку он отправляет вызов по сети
- Запомните, хотя ,
await
в данной точке не позволяют дальнейшему коду обрабатывать модули одного и того же метода, даже если он освобождает поток, поэтому лучше, если существует несколько независимых вызовов, они агрегируются с использованием Task.WhenAll
, и ожидается репрезентативная задача, которая вернется, когда все они завершат успех / ошибку, что когда-либо может быть состоянием
- Если между асинхронным прерыванием используется что-то вроде
Task.Wait
или Task.Result
, он не останется чистым асинхронным вызовом и заблокирует поток пула вызывающих потоков
Как можно улучшить Async?
- В вызовах библиотеки Pure, когда Async инициируется пулом потоков, а поток диспетчеризации может отличаться от получаемого, и вызову не нужно повторно вводить тот же контекст, вы должны использовать
ConfigureAwait(false)
, что означает, что он не будет ждать повторно войти в исходный контекст и повышение производительности
- Как и
await
имеет смысл использовать ConfigureAwait(false)
через цепочку, вход в конец. Это действительно только для библиотек, которые широко отвечают на пулы потоков
Есть ли созданная тема
- Лучше прочитайте это, Стивен Клири - Нет темы
- Подлинный асинхронный вызов ввода-вывода будет использовать аппаратный параллелизм для обработки, не будет блокировать
Программные Потоки
Изменения
- Асинхронная обработка на базе процессора, где вы берете вещи в фоновом режиме, поскольку текущий поток должен быть отзывчивым, в основном в случае Ui, например WPF
Примеры использования
- Все виды систем, особенно не-MS Framework, такие как узел js, имеют асинхронную обработку в качестве базового принципа, и кластер сервера базы данных на принимающей стороне настроен на получение миллионов вызовов и их обработку
- B2C вызовыОжидается, что каждый запрос является легковесным с ограниченной полезной нагрузкой
Редактировать 1:
Только в этом конкретном случае, как указано здесь , ToListAsync
по умолчанию является асинхронным, поэтому в этом случае вы можете пропустить асинхронное ожидание, как указано в комментариях к вариопусу, хотя в общем случае ознакомьтесь со статьей Стефана Клили, которая может быть не очень хорошей стратегией, поскольку выгоды минимальны и негативное влияние на неправильностьиспользование может быть высоким