高级:HttpModule Init()方法在应用程序生命期间被调用多少次? [英] Advanced: How many times does HttpModule Init() method get called during application's life?
问题描述
Web应用初始化如下:
- 正如我们所知,当IIS收到特定Asp.net应用程序资源的第一个请求时, IIS创建一个
HttpApplication
(在global.asax
codebehind中定义)的实例。 - 然后将所有模块实例化并放入应用程序的
模块
中, code>集合(类型为 - 模块循环,他们的
Init()
方法被调用(当他们注册请求事件时)
HttpModuleCollection
) 据我所知,上述情况发生在Web应用程序启动/初始化(因此应用程序启动事件)时。
模块会发生什么?
他们(re)是否在每个请求上进行调整,或者从 Modules
prope中重用在web应用程序还活着的时候,每个连续请求都有rty?据了解IIS和Asp.net,它们在网络应用程序的整个生命周期中被重用。
如果它们被重用,我们可以假定他们的 Init()
方法实际上是一个用于应用程序启动事件的伪事件处理程序?事情是我们无法附加到http模块中的应用程序级事件。但是如果它们被重用,我们可以使用 Init()
作为应用程序启动事件,并做任何我们将放在 global.asax
问题
我们可以假设该模块的 Init()
方法在应用程序启动事件中仅称为 ?我们可以使用这个假设,即为 global.asax
codebehind我们不能改变的应用程序注册路由? web.config
通常可以访问,我们可以按照我们想要的方式进行更改。
这是否真的有效?
附加信息
我们可以检查 HttpApplication
代码并检查其 InitModulesCommon()
方法。这个实际上调用每个注册的HTTP模块的 Init()
。更有趣的是,这种方法只能由 InitIntegratedModules()
和 InitModules()
方法使用。在 HttpApplication.InitInternal()
方法中仅使用 。这是我的假设的基础,但是我想知道是否有人对应用程序启动事件滥用了 IHttpModule.Init()
。
Init()
只调用一次(每个 HttpApplication
实例)
在我测试了这个之后,$ code> IHttpModule 初始化的内部工作原理如下:
- 每个
IHttpModule
在Web应用程序开始时初始化,并调用Init()
方法 -
HttpApplication
将所有模块实例存储在其模块中
属性 - 模块然后在
HttpApplication
的一生中重复使用,不会被丢弃/重新初始化为只要应用程序存活
所以最好的结果是
你不能将 IHttpModule
附加到应用程序级事件,但您ca n将其 Init()
方法用作伪应用程序启动事件委托。在里面你可以执行你通常放在你的 Global.asax
中 Application_Start p>
您还可以在我的博客。
但在现实生活的网络服务器环境中要小心
但是IIS使用了一些名为应用程序池的东西。每个池可以有任意数量的 HttpApplication
实例。是多个。应用启动创建所有这些实例。他们每个都初始化自己的模块列表,但只有第一个执行 Application_OnStart
事件处理程序。
所以每当您的模块修改一些共同的共享资源时,您应该采取额外的措施来表明第一个模块已经完成,而其他模块不会再执行。阅读关于它的其他博客文章这将告诉您如何和何时使用线程锁定与您的模块,使其实际上作为一个 Application_OnStart
事件处理程序。 BTW:如果需要,还可以处理 Application_OnEnd
事件。 ;)
详细的博客文章链接
Web application initialization is as follows:
- As we know when IIS receives the first request for a particular Asp.net application resource, IIS creates an instance of a
HttpApplication
(defined inglobal.asax
codebehind). - When this new instance is created it's initialization happens that also checks all configured HTTP modules.
- All modules are then instantiated and put in the application's
Modules
collection (of typeHttpModuleCollection
) - modules are looped through and their
Init()
method is called (when they register for request events)
As far as I understand it the above scenario happens when a web application is started/initialized (hence application start event).
What happens with modules?
Are they (re)instatiated on each request or reused from the Modules
property on each consecutive request while the web application is alive? As I understand IIS and Asp.net they are reused through the whole life of a web application.
If they are reused, can we assume that their Init()
method is actually a pseudo event handler for application start event? The thing is we can't attach to application level events within http modules. But if they are being reused we could use Init()
as application start event and do whatever we'd put in global.asax
instead.
Question
Can we assume that module's Init()
method is called only on application start event? Could we use this assumption to i.e. register routes for applications whose global.asax
codebehind we can't change? web.config
is usually accessible and we can change it the way we want.
Would this actually work?
Additional info
We can check HttpApplication
code and check its InitModulesCommon()
method. This one actually calls Init()
of each registered HTTP module. What is more interesting is that this method is only used by InitIntegratedModules()
and InitModules()
methods. Which are both used only in HttpApplication.InitInternal()
method. This is the basis of my assumptions, but I would like to know whether someone has abused IHttpModule.Init()
for application start event.
Init()
is called only once (per HttpApplication
instance)
After I tested this the inner workings of IHttpModule
initialization are as follows:
- Every
IHttpModule
is initialized at web application start by instatiating and a call toInit()
method HttpApplication
stores all module instances in itsModules
property- Modules are then reused for the whole life of an
HttpApplication
and are not discarded/reinitialized as long as the application is alive
So the best outcome is
You can't attach an IHttpModule
to application level events, but you can use its Init()
method as pseudo application start event delegate. Inside it you can execute any code that you'd usually put inside Application_Start
delegate in your Global.asax
.
You can also read detailed information about it in my blog post.
But be careful in real-life web server environment
But IIS uses something called application pools. And each pool can have an arbitrary number of HttpApplication
instances. Yes multiple. Application starting creates all these instances. Every one of them initializes their own list of modules but only the first one executes the Application_OnStart
event handler.
So whenever your module modifies some common shared resource, you should take extra measures to indicate that the first module has done that and others won't do it again. Read an additional blog post about it that will show you how and when to use thread locking with your module to make it actually act as an Application_OnStart
event handler. BTW: It's also possible to handle Application_OnEnd
event if you need to. ;)
Detailed blog post links
- Writing a custom IHttpModule that handles Application_OnStart event
- How to correctly use IHttpModule to handle Application_OnStart event
这篇关于高级:HttpModule Init()方法在应用程序生命期间被调用多少次?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!