我正在创建一个http模块,并且在调试时我注意到了一些起初(至少)似乎很奇怪的行为。HttpModule Init方法被多次调用 - 为什么?
当我在httpmodule的init方法中设置断点时,我可以看到http模块init方法被多次调用,即使我只启动了网站进行调试并发出一个请求(有时它只打1次,其他时间打10次)。
我知道我应该期待HttpApplication的几个实例运行,并且每个http模块都将被创建,但是当我请求单个页面时,它应该由单个http应用程序对象处理,因此只会触发事件关联一次,但它仍然会为每个请求触发事件几次,这是没有意义的 - 除了它必须在该httpApplication中添加多次 - 这意味着它是每次都调用相同的httpmodule init方法,而不是一个新的http应用程序正在创建每次它击中我的中断点(请参阅我的代码示例在底部等)。
这里可能会出现什么问题?是因为我正在调试并在http模块中设置断点?
它已经注意到,如果我启动网站进行调试并快速跨越httpmodule中的断点,它只会触发init方法一次,对于事件处理程序也是如此。如果我让它在断点处停留几秒钟,init方法会被多次调用(看起来好像取决于在跨越断点之前等待的时间)。也许这可能是一些功能的构建,以确保httpmodule已初始化,并且http应用程序可以为请求提供服务,但它似乎也可能具有灾难性后果。
这可能似乎是合乎逻辑的,因为它可能会尝试完成请求,因为我已经设置了断点就觉得某件事情出现了问题,并尝试再次调用init方法?所以它可以处理请求?
但是,这是怎么回事,是一切正常(我只是猜测),还是真正的问题?
我特别关心的是,如果有什么东西让它挂在“生产/生活”服务器上几秒钟,很多事件处理程序会通过init被添加,因此每个页面请求都会触发事件处理程序几次。
此行为可能会迅速导致任何网站停机。
我已经看过用于针对的HttpModules和formsauthentication的rolemanagermodule等“原始”的.NET代码,但我的心不是代码有什么不同,这些模块使用。
我的代码看起来像这样。
public void Init(HttpApplication app)
{
if (CommunityAuthenticationIntegration.IsEnabled)
{
FormsAuthenticationModule formsAuthModule = (FormsAuthenticationModule) app.Modules["FormsAuthentication"];
formsAuthModule.Authenticate += new FormsAuthenticationEventHandler(this.OnAuthenticate);
}
}
这里有一个例子它是如何在RoleManagerModule从.NET框架
public void Init(HttpApplication app)
{
if (Roles.Enabled)
{
app.PostAuthenticateRequest += new EventHandler(this.OnEnter);
app.EndRequest += new EventHandler(this.OnLeave);
}
}
不要任何人都知道是怎么回事呢?
(我只是希望有人在那里能告诉我为什么发生这种情况,并确保我一切都完美的罚款):)
UPDATE:
我试图缩小问题到目前为止,我发现被调用的Init方法总是在我的http模块的一个新对象上(我以前认为的)。
我看起来对于第一个请求(启动站点时),所有正在创建的HttpApplication对象及其模块都尝试服务于第一个请求,因此所有都碰到了正在添加的事件处理程序。 我真的不知道为什么会发生这种情况。
如果我请求另一个页面,所有创建的HttpApplication(和它们的无模块)将再次尝试服务请求,导致它多次触发事件处理程序。
但它似乎也是,如果我然后跳回到第一页(或另一个)只有一个HttpApplication将开始照顾请求和一切都如预期的 - 只要我不让它挂在一个断点。
如果我让它在断点处挂起,它会开始创建新的HttpApplication对象并开始添加HttpApplications(多于1个)来处理/处理请求(它已经处于由当前停止的HttpApplication处理的过程中在断点处)。
我猜想或希望它可能是一些智能的“幕后”方式来帮助分发和处理负载和/或错误。但我不知道。 我希望有些人可以向我保证,这是完美的,它应该如何?
我在我们的HttpModule中看到了这种行为 – 2009-10-16 16:46:52
John:我忘了关闭这个。它发生(至少在我的情况下),因为该模块受到浏览器对任何资源(图像,JavaScript,样式表)的每一个请求的影响。它受到打击的原因是在MVC中使用的路由模块。所有请求都需要由路由模块处理,因此所有请求都会不幸地触发模块。我曾问过这个问题,但没有人回答。 – MartinF 2009-10-27 03:32:14