|
Я помітив, що багато друзів, як і я, помилково використовували IHttpModule.Init як Application_Start альтернативу для виконання операцій ініціалізації додатків у ньому. Однак природа подій Application_Start в IHttpModule.Init та Global.asax відрізняється, і IHttpModule.Init не може бути використаний безпосередньо для заміни процесу ініціалізації Application_Start ASP.NET додатку. Також не можна просто зробити висновок, що метод Init неодноразово закликається до висновку, що ASP.NET програму було перезапущено. Причина в тому, що IHttpModule.Init може бути викликаний кілька разів при відповіді на запит ASP.NET, і це дуже ймовірно відбувається під час роботи сайту. Чому IHttpModule.Init викликається кілька разів? Оскільки кожен екземпляр HttpApplication може обробляти лише один запит одночасно, і ASP.NET підтримує певну кількість одночасних запитів, тому екземпляр HttpApplication створюється кілька разів для відповіді на різні запити, коли цього недостатньо для відповіді на паралельні запити. Кожен екземпляр HttpApplication створює новий набір HttpModules і викликає метод Init після його створення. Application_Start буде викликано лише після створення першого об'єкта HttpApplication, і наступні екземпляри HttpApplication не запускатимуть цю подію. Я вважаю, що повторне використання екземплярів HttpApplication є однією з головних причин неправильного розуміння використання методу Init у IHttpModule, оскільки зазвичай при налагодженні програми є лише один запит, і практично неможливо багаторазово виконувати метод Init від HttpModule. У реальному середовищі роботи сайту одночасні запити є поширеними, і якщо метод Init використовується неправильно, це може спричинити дивні проблеми в реальному середовищі. Для конкретних деталей, будь ласка, зверніться до статті MSDN «Огляд життєвого циклу ASP.NET додатку для IIS 5.0 та 6.0», де наведено зображення в статті: Ви також можете використовувати Refelector для декомпіляції асемблеру System.Web і аналізу зв'язку виклику методу IHttpModule.Init. У результаті ви отримаєте метод System.Web.HttpApplicationFactory.GetNormalApplicationInstance, який показує, як екземпляри HttpApplication повторно використовуються та створюються. Підсумовуючи, IHttpModule.Init не можна просто використовувати як заміну Application_Start. Відносно простий спосіб — використати статичне поле типу bool як тег ініціалізації, встановити позначки на true після ініціалізації, необхідної програмі в HttpModule, і не повторювати цю ініціалізацію наступного разу. Однак код, наприклад, реєстрація події BeginRequest, все одно має виконуватися щоразу при виконанні Init, оскільки інстанс HttpModule у цей момент відрізняється: якщо оцінити поле розмітки статичної ініціалізації без повторення події реєстрації, це призведе до дивних проблем, наприклад, переписування URL іноді виконується, а іноді ні.
[Міф] Чи буде метод Init об'єкта HttpApplication виконуватися лише один раз?
Відповідь: Це буде виконано кілька разів!!!!
|