【发布时间】:2010-11-11 13:44:34
【问题描述】:
我正在创建一个 http 模块,在调试时我注意到一开始(至少)看起来很奇怪的行为。
当我在 httpmodule 的 init 方法中设置断点时,我可以看到 http module init 方法 被多次调用,即使我只是启动网站进行调试并做了一个单个请求(有时只被命中 1 次,有时多达 10 次)。
我知道我应该期望 HttpApplication 的多个实例正在运行,并且将为每个实例创建 http 模块,但是当我请求单个页面时,它应该由单个 http 应用程序处理对象,因此只触发一次关联的事件,但它仍然为每个请求触发事件多次,这是没有意义的 - 除了它必须在该 httpApplication 中添加多次 - 这意味着它是每次都调用相同的 httpmodule init 方法,而不是每次遇到断点时都创建一个新的 http 应用程序(参见底部的代码示例等)。
这里可能出了什么问题?是不是因为我在调试,在http模块中设置了断点?
它已经注意到,如果我启动网站进行调试并快速跨过 httpmodule 中的断点,它似乎只会命中一次 init 方法, 也是如此事件处理程序。如果我让它在断点处挂起几秒钟,则 init 方法 将被调用多次(似乎这取决于我在越过断点之前等待的时间)。也许这可能是一些内置功能,以确保 httpmodule 已初始化并且 http 应用程序可以服务请求,但它似乎也可能产生灾难性后果。
这似乎是合乎逻辑的,因为它可能正在尝试完成请求,并且由于我设置了断点,它认为出现问题并再次尝试调用 init 方法?那么它可以处理请求吗?
但这是正在发生的事情吗?一切都很好(我只是在猜测),还是一个真正的问题?
我特别担心的是,如果某些东西使它在“生产/实时”服务器上挂起几秒钟,则会通过 init 添加大量事件处理程序,因此每个请求都会页面突然触发 eventhandler 几次。
这种行为可能会迅速导致任何网站宕机。
我查看了用于 formsauthentication 和 rolemanagermodule 等的 httpmodules 的“原始”.net 代码……但我的代码并没有什么不同这些模块使用。
我的代码如下所示。
public void Init(HttpApplication app)
{
if (CommunityAuthenticationIntegration.IsEnabled)
{
FormsAuthenticationModule formsAuthModule = (FormsAuthenticationModule) app.Modules["FormsAuthentication"];
formsAuthModule.Authenticate += new FormsAuthenticationEventHandler(this.OnAuthenticate);
}
}
这是一个示例,它是如何在 .NET 框架的 RoleManagerModule 中完成的:
public void Init(HttpApplication app)
{
if (Roles.Enabled)
{
app.PostAuthenticateRequest += new EventHandler(this.OnEnter);
app.EndRequest += new EventHandler(this.OnLeave);
}
}
有人知道怎么回事吗?
(我只是希望有人能告诉我为什么会这样,并向我保证一切都很好):)
更新:
我试图缩小问题的范围,到目前为止我发现被调用的 init 方法总是在我的 http 模块的一个新对象上(与我之前的想法相反)。
我似乎对于第一个请求(启动站点时),所有正在创建的 HttpApplication 对象及其模块都试图为第一个请求提供服务,因此都命中了 正在添加的事件处理程序。 我真的不明白为什么会这样。
如果我请求另一个页面,所有 HttpApplication 创建的(及其模块)将再次尝试服务请求,导致它多次点击 eventhandler。
但似乎如果我随后跳回第一页(或另一页),只有一个 HttpApplication 将开始处理请求,并且一切都按预期进行 - 只要我不要让它在断点处挂起。
如果我让它挂在断点上,它会开始创建新的 HttpApplication 对象并开始添加 HttpApplications(超过 1 个)来服务/处理请求( HttpApplication 正在为它提供服务,该 HttpApplication 当前在断点处停止)。
我猜想或希望这可能是一种帮助分配和处理负载和/或错误的智能“幕后”方式。但我不知道。 我希望那里的一些人可以向我保证它非常好,它应该是怎样的?
【问题讨论】:
-
我在我们的 HttpModule 中也看到了这种行为
-
约翰:我忘了关这个。它发生(至少在我的情况下)是因为模块被浏览器对任何资源(图像、javascript、样式表)发出的每个请求所击中。它被击中的原因是 etc MVC 中使用的路由模块。所有请求都需要由路由模块处理,因此不幸的是所有请求都命中了该模块。我已经问过这个问题,但没有人回答。
标签: c# .net httpmodule init