本文介绍了高级:HttpModule Init()方法在应用程序生命期间被调用多少次?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

Web应用初始化如下:


  1. 正如我们所知,当IIS收到特定Asp.net应用程序资源的第一个请求时, IIS创建一个 HttpApplication (在 global.asax codebehind中定义)的实例。


  2. 然后将所有模块实例化并放入应用程序的模块
  3. 中, code>集合(类型为 HttpModuleCollection )
  4. 模块循环,他们的 Init() 方法被调用(当他们注册请求事件时)

据我所知,上述情况发生在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 初始化的内部工作原理如下:


  1. 每个 IHttpModule 在Web应用程序开始时初始化,并调用 Init()方法

  2. HttpApplication 将所有模块实例存储在其模块中属性

  3. 模块然后在 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:

  1. As we know when IIS receives the first request for a particular Asp.net application resource, IIS creates an instance of a HttpApplication (defined in global.asax codebehind).
  2. When this new instance is created it's initialization happens that also checks all configured HTTP modules.
  3. All modules are then instantiated and put in the application's Modules collection (of type HttpModuleCollection)
  4. 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:

  1. Every IHttpModule is initialized at web application start by instatiating and a call to Init() method
  2. HttpApplication stores all module instances in its Modules property
  3. 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

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

这篇关于高级:HttpModule Init()方法在应用程序生命期间被调用多少次?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

10-11 13:10