Ответ 1
ASP.NET использует пул потоков для обработки входящих HTTP-запросов.
Когда вызывается IHttpHandler, для выполнения этого запроса используется поток пула потоков, и тот же поток используется для обработки всего запроса. Если этот запрос вызывается в базу данных или другую веб-службу или что-то еще, что может занять время, поток потока потоков ждет. Это означает, что потоки пула потоков тратят время на то, когда они могут быть использованы для обработки других запросов.
В отличие от этого, когда у IHttpAsyncHandler существует механизм, позволяющий запросу регистрировать обратный вызов и возвращать поток пула потоков в пул до того, как запрос будет полностью обработан. Поток пула потоков начинает выполнять некоторую обработку для запроса. Вероятно, вызывает некоторый метод асинхронизации в вызове базы данных или веб-службе или что-то еще, а затем регистрирует обратный вызов для ASP.NET для вызова, когда этот вызов возвращается. В этот момент поток пула потоков, который обрабатывал HTTP-запрос, возвращается в пул для обработки другого HTTP-запроса. Когда вызов базы данных или что-то еще возвращается, ASP.NET запускает зарегистрированный обратный вызов в потоке пула потоков. Конечный результат: у вас нет потоков потоков потоков, ожидающих операции с привязкой к вводу-выводу, и вы можете более эффективно использовать свой пул потоков.
Для очень высоких приложений concurrency (сотни или тысячи действительно одновременных пользователей) IHttpAsyncHandler может обеспечить огромный прирост в concurrency. При меньшем количестве пользователей все равно может быть полезно, если у вас очень длинные запросы (например, запрос Long Polling). Однако программирование под IHttpAsyncHandler является более сложным, поэтому его нельзя использовать, когда оно действительно не требуется.