Web应用程序初始化如下:
HttpApplication
的实例(在global.asax
代码隐藏中定义)。Modules
集合(类型HttpModuleCollection
)Init()
方法(当它们注册请求事件时)据我了解,上述情况发生在启动/初始化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()
申请启动事件。
答案 0 :(得分:31)
Init()
仅被调用一次(每HttpApplication
个实例)在我测试之后,IHttpModule
初始化的内部工作原理如下:
IHttpModule
都会在网络应用程序初始化时通过实施和调用Init()
方法HttpApplication
将所有模块实例存储在其Modules
属性HttpApplication
的整个生命周期中重复使用,并且只要应用程序处于活动状态就不会被丢弃/重新初始化您无法将IHttpModule
附加到应用程序级事件,但可以将其Init()
方法用作伪应用程序启动事件代理。在其中,您可以执行Application_Start
中Global.asax
委托中通常放置的任何代码。
您还可以在我的blog post中阅读有关它的详细信息。
但IIS使用的是名为应用程序池的东西。每个池可以有任意数量的HttpApplication
个实例。是多个。应用程序启动创建所有这些实例他们每个人都初始化自己的模块列表,但只有第一个模块执行Application_OnStart
事件处理程序。
因此,每当您的模块修改某些常见的共享资源时,您应该采取额外的措施来指示第一个模块已经完成该操作,而其他模块则不会再次执行此操作。阅读有关它的additional blog post,它将向您展示如何以及何时使用模块进行线程锁定,以使其实际上充当Application_OnStart
事件处理程序。顺便说一句:如果需要,也可以处理Application_OnEnd
事件。 ;)
答案 1 :(得分:3)
Application_Start仅在应用程序的生命周期内运行一次。
在请求处理开始之前,为每个HttpApplication实例运行IHttpModule.Init。请参阅walkthrough。 Init是您可以注册用于处理请求的事件的地方。
HttpApplication的实例可以重用于多个请求。 ASP.Net汇集了HttpApplication对象,因此每次为HttpApplication的新实例调用一次Init