В какой степени асинхронные события HttpApplication (например, зарегистрированные с использованием AddOnEndRequestAsync
и друзей) асинхронны? Является ли IIS ожидающим, чтобы все асинхронные события, запущенные для конкретного события, завершились, прежде чем переходить к следующему событию, или они «стреляют и забывают»?Выполняют ли асинхронные события HttpApplication, пока они не вернутся?
ответ
Непонятно, какие именно операции выполняются в режиме интегрированного конвейера, но я могу рассказать вам, что я вижу для неинтегрированного случая, и семантика должна оставаться неизменной.
Короткий ответ заключается в том, что каждый обработчик событий запускается последовательно, синхронно или асинхронно, а следующий не запускается до тех пор, пока предыдущий не завершится.
Вы можете проследить это через исходный код.
Запрос приходит и хранится в очереди. Как правило, когда HttpRuntime
отменяет запрос, он инициализирует HttpApplication
для запроса, вызывая его метод InitInternal
, передавая HttpContext
в качестве аргумента.
HttpApplication.InitInternal
инициализирует новый класс HttpApplication.ApplicationStepManager
для случая не интегрированного режима. Затем вы можете увидеть, что он называет метод BuildSteps
. Это создает ArrayList
для хранения шагов и конструкций и сохраняет все этапы. В частности, эти этапы представляют собой реализации интерфейса IExecuteStep
. В конечном счете, когда все шаги добавлены, список завершается копированием его в массив и сохранением его для более позднего элемента var _execSteps
.
Существует несколько источников шагов, но наиболее часто используемыми вы видите HttpApplication.CreateEventExecutionSteps
, который принимает тип события (начало запроса, авторизация и т. Д.) И массив шагов, чтобы добавить его шаги для этого события. Если вы свернете на CreateEventExecutionSteps
, вы увидите, что он добавляет IExecuteStep
для каждого асинхронного и обработчика синхронизации, о котором он знает, из таблиц AsyncEvents
и Events
, соответственно. Интерфейс IExecuteStep
сам по себе состоит из Execute
и CompletedSynchronously
.
Теперь остановитесь и посмотрите на один из методов Добавить, как вы упомянули, AddOnEndRequestAsync
, и вы можете увидеть его, чтобы добавить информацию об обработчике async в таблицу AsyncEvents
. CreateEventExecutionSteps
будет проходить через этот стол, и для каждого обработчика будет создан AsyncEventExecutionStep
.
Обратно к потоку запросов. После того, как HttpRuntime
инициализирует HttpApplication
для запроса, он вызывает свой метод BeginProcessRequest
, который запускает ResumeSteps
.
ResumeSteps
является важным, когда вы можете увидеть, как этапы используются и что ждет стратегия ожидания в асинхронном случае. Вы можете видеть, что он поддерживает _currentStepIndex
в массив шагов выполнения. В конце концов вы увидите, что он захватывает следующий шаг из массива и вызывает его метод Execute
. Если на шаге сообщается, что его выполнение CompletedSynchronously
, оно циклически и снова идет. Если нет, он позволяет методу закончить и войти в асинхронную абис.
Чтобы посмотреть, что произойдет в этом асинхронном случае, вы должны посмотреть на реализацию AsyncEventExecutionStep
, которая была создана для обработчиков async. В своей реализации Execute
вы видите, что он запускает обработчик начала и передает обратный вызов завершения. В конструкторе вы видите, что этот обратный вызов инициализирован методом, который в конечном итоге вызывает ... HttpApplication.ResumeSteps
еще раз!
И так оно продолжается, выполняет шаги, синхронизирует или асинхронно, пока массив не переполняется, и в этот момент он «завершает» обработку запроса.
Дело в том, что вы можете четко видеть, что шаги, которые переводят обработчики событий, которые вы добавляете, выполняются один за другим, а также синхронизация или асинхронный процесс, следующие шаги не выполняются до тех пор, пока не будет выполнен текущий шаг. Ваш вопрос заключался в том, обрабатываются ли события один за другим таким образом, но, как вы видите, на самом деле он еще более гранулирован, причем каждый обработчик событий обрабатывается таким образом, поэтому каждый получает синхронизированный доступ к HttpContext и может работать без беспокоясь о том, остаются ли они «в правильной фазе» трубопровода.
Очевидно, что в этом исходном коде есть другие детали, yada yada, но это суть.
- 1. Являются ли общественные события асинхронными? Выполняют ли они отдельный поток?
- 2. Остановить операции mysql, пока все не вернутся.
- 3. Выполнять вызовы mulitple в Mongo, а затем ждать, пока они все вернутся
- 4. Выполняют ли события jQuery для элементов объекта?
- 5. Как запустить несколько функций до тех пор, пока они не вернутся?
- 6. Как проверить HttpApplication события в IHttpModules
- 7. асинхронные события, которые запускаются
- 8. HttpApplication не уходит
- 9. Асинхронные и .NET-события?
- 10. android traceview асинхронные события
- 11. Выполняют ли исполнители тему, из которой они были созданы?
- 12. Асинхронные события модуля тестирования
- 13. Вернутся окно Трассировка не работает
- 14. Асинхронные сервлеты не выполняют задачу async в отдельном потоке
- 15. Как TDD асинхронные события?
- 16. Асинхронные события Javascript
- 17. Ruby: зачем делать и пока не вернуть последнюю строку, которую они выполняют из функции?
- 18. Может ли autotools Makefiles отображать команды, которые они выполняют?
- 19. Асинхронные события, не выводимые на консоль
- 20. Должен ли я отказаться от подписки на все мои события контроллеров, пока они не нужны?
- 21. Как они выполняют поиск внутри строки
- 22. Подождите, пока завершатся вложенные асинхронные вызовы
- 23. Javascript Асинхронные события излучает механизм
- 24. Почему некоторые ячейки изменяются, даже если они не выполняют условие?
- 25. Выполняют ли все события в захвате javascript и пузыре?
- 26. Выполняют ли события браузера и обработку цикла событий одним потоком?
- 27. Подождите, пока асинхронные запросы async завершатся
- 28. Работают ли события, если они возникают асинхронно?
- 29. JavaScript Подождите, пока все асинхронные вызовы закончатся
- 30. веб, пока они не имеют один