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

时间:2010-07-30 11:02:10

标签: asp.net events httpmodule

Web应用程序初始化如下:

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

    模块会发生什么?

    在Web应用程序处于活动状态时,是否(重新)对每个请求进行了实例化,或者在每个连续请求中从Modules属性重用?据我了解IIS和Asp.net,它们在Web应用程序的整个生命周期中都被重用。

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

    问题

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

    其他信息

    我们可以检查HttpApplication代码并检查其InitModulesCommon()方法。这个实际上调用了每个注册的HTTP模块的Init()。更有趣的是,此方法仅由InitIntegratedModules()InitModules()方法使用。哪些都在HttpApplication.InitInternal()方法中使用 。这是我的假设的基础,但我想知道是否有人滥用IHttpModule.Init()申请启动事件。

2 个答案:

答案 0 :(得分:31)

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

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

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

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

    您还可以在我的blog post中阅读有关它的详细信息。

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

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

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

    详细的博客文章链接

    1. Writing a custom IHttpModule that handles Application_OnStart event
    2. How to correctly use IHttpModule to handle Application_OnStart event

答案 1 :(得分:3)

Application_Start仅在应用程序的生命周期内运行一次。

在请求处理开始之前,为每个HttpApplication实例运行

IHttpModule.Init。请参阅walkthrough。 Init是您可以注册用于处理请求的事件的地方。

HttpApplication的实例可以重用于多个请求。 ASP.Net汇集了HttpApplication对象,因此每次为HttpApplication的新实例调用一次Init