Что вы действительно спрашиваете, так это разницу между синхронизацией и асинхронностью. В очень базовых терминах async допускает возможность переключения потоков, т. Е. Работа начинается в одном потоке, но заканчивается в другом, тогда как синхронизация выполняется в том же потоке.
Это само по себе мало что значит без контекста того, что происходит в конкретном приложении. В случае веб-приложения у вас есть пул потоков. Пул потоков , как правило, , состоит из 1000 потоков, что является типичным значением по умолчанию для веб-серверов. Это число может быть меньше или больше; это не очень важно для этой дискуссии. Однако важно отметить, что существует очень реальное физическое ограничение на максимальное количество потоков в пуле. Поскольку каждый из них потребляет некоторое количество системных ресурсов.
Этот пул потоков часто также называют «максимальными запросами», поскольку, вообще говоря, один запрос = один поток. Поэтому, если у вас есть пул потоков 1000, вы можете теоретически обслуживать 1000 одновременных запросов. Все, что попадает в очередь, попадает в очередь и будет обработано, как только один из потоков станет доступным. Вот тут и приходит асинхронность.
Асинхронная работа - это в значительной степени работа ввода-вывода: запросы к базе данных, чтение / запись в файловую систему, отправка запроса к другой службе, такой как API, и т. Д. При всем этом обычно существует некоторый период простоя время. Например, с запросом к базе данных вы делаете запрос, а затем ждете. Требуется некоторое время для того, чтобы запрос поступил на сервер базы данных, чтобы сервер базы данных обработал его и сгенерировал набор результатов, а затем чтобы сервер базы данных отправил результат обратно. Async позволяет активному потоку быть возвращенным в пул в течение таких периодов, где он может затем обслуживать другие запросы. Таким образом, при условии, что у вас есть подобное действие, которое выполняет запрос к базе данных, если оно было синхронизировано и вы получили 1001 одновременный запрос к этому действию, первая 1000 начнет обработку, а последняя будет в очереди. Этот последний запрос не может быть обработан, пока одна из остальных 1000 не будет полностью завершена. Принимая во внимание, что с помощью async, как только одна из тысячи передала запрос серверу базы данных, он мог быть возвращен в пул потоков для обработки этого ожидающего запроса.
Это все немного на высоком уровне. На самом деле, есть лот , который входит в это, и это действительно не так просто. Async не гарантирует, что поток будет освобожден. Определенная работа, в частности работа с привязкой к процессору, никогда не может быть асинхронной, поэтому, даже если вы делаете это в асинхронном методе, она выполняется так, как если бы она была синхронизированной. Однако, вообще говоря, async будет обрабатывать больше запросов, чем синхронизировать в сценарии, где ваш поток истощает. Это приходит по цене, хотя. Эта дополнительная работа по переключению между потоками добавляет некоторую дополнительную нагрузку, даже если она минимальна, поэтому асинхронность почти всегда будет медленнее, чем синхронизация, даже хотя бы на наносекунды. Однако асинхронность составляет масштаб , а не производительность, и снижение производительности, как правило, является приемлемой сделкой для увеличения способности к масштабированию.