高级:在应用程序生命周期中调用HttpModule Init()方法多少次?

Rob*_*nik 26 asp.net events httpmodule

Web应用程序初始化如下:

  1. 正如我们所知,IIS收到特定Asp.net应用程序资源的第一个请求时,IIS会创建一个HttpApplication(在代码global.asax隐藏中定义)的实例.
  2. 创建此新实例时,会进行初始化,同时检查所有已配置的HTTP模块.
  3. 然后将所有模块实例化并放入应用程序的Modules集合中(类型HttpModuleCollection)
  4. 模块循环并Init()调用它们的方法(当它们注册请求事件时)

据我所知,上面的场景发生在Web应用程序启动/初始化时(因此应用程序启动事件).

模块会发生什么?

Modules在Web应用程序处于活动状态时,它们是在每个请求上重新设置还是在每个连续请求中从属性重用?据我了解IIS和Asp.net,它们在Web应用程序的整个生命周期中被重用.

如果它们被重用,我们可以假设它们的Init()方法实际上是应用程序启动事件的伪事件处理程序吗?问题是我们无法附加到http模块中的应用程序级别事件.但是,如果它们被重用,我们可以将其Init()用作应用程序启动事件,并执行我们所做的任何事情global.asax.

我们可以假设模块的Init()方法在应用程序启动事件时调用吗?我们可以使用这个假设来注册global.asax我们无法改变其代码隐藏的应用程序的路由吗?web.config通常是可访问的,我们可以按照我们想要的方式进行更改.
这实际上有用吗?

附加信息

我们可以检查HttpApplication代码并检查其InitModulesCommon()方法.这个实际调用Init()每个注册的HTTP模块.更有趣的是,这种方法仅用于InitIntegratedModules()InitModules()方法.哪些都只用于HttpApplication.InitInternal()方法.这是我的假设的基础,但我想知道是否有人滥用IHttpModule.Init()应用程序启动事件.

Rob*_*nik 32

Init()只调用一次(每个HttpApplication实例)

在我测试之后,IHttpModule初始化的内部工作原理如下:

  1. 每个IHttpModule都是在Web应用程序启动时通过instatiating和Init()方法调用初始化的
  2. HttpApplication将所有模块实例存储在其Modules属性中
  3. 然后,模块在整个生命周期中重复使用,HttpApplication并且只要应用程序处于活动状态,模块就不会被丢弃/重新初始化

所以最好的结果是

您无法附加IHttpModule应用程序级别事件,但可以将其Init()方法用作伪应用程序启动事件委托.在其中,您可以执行您通常放在Application_Start代理中的任何代码Global.asax.

您还可以在我的博客文章中阅读有关它的详细信息.

但在现实生活中的Web服务器环境中要小心

但IIS使用称为应用程序池的东西.每个池可以有任意数量的HttpApplication实例.是多个.应用程序启动创建所有这些实例 他们每个人都初始化自己的模块列表,但只有第一个执行Application_OnStart事件处理程序.

因此,每当您的模块修改一些常见的共享资源时,您应该采取额外的措施来指示第一个模块已经完成了该操作,而其他模块则不会再次执行此操作.阅读关于它的其他博客文章,它将向您展示如何以及何时使用模块进行线程锁定,以使其实际充当Application_OnStart事件处理程序.顺便说一句:Application_OnEnd如果需要,也可以处理事件.;)

详细的博客文章链接

  1. 编写处理Application_OnStart事件的自定义IHttpModule
  2. 如何正确使用IHttpModule来处理Application_OnStart事件

  • @MatteS:以什么方式误导?这是完全正确的,因为每个`HttpApplication`实例只调用一次`Init`.当一个人读完整个答案(他们应该)时,他们就会明白如何处理自己的问题. (8认同)