我正在创建一个 http 模块,在调试时我注意到一些起初(至少)看起来很奇怪的行为。
当我在 httpmodule 的 init 方法中设置断点时,我可以看到http 模块的 init 方法被调用了几次,即使我只是启动了网站进行调试并发出了一个请求(有时它只被命中 1 次, 其他次数多达 10 次)。
我知道我应该期望HttpApplication的多个实例正在运行,并且将为每个实例创建 http 模块,但是当我请求单个页面时,它应该由单个 http 应用程序对象处理,因此只触发一次关联的事件,但它仍然为每个请求触发事件多次,这是没有意义的 - 除了它必须在该httpApplication中添加多次- 这意味着它是每次调用的相同httpmodule init 方法,而不是新的 http 应用程序每次遇到断点时都会创建(请参阅底部的代码示例等)。
这里可能出了什么问题?是不是因为我在调试,在http模块中设置了断点?
它已经注意到,如果我启动网站进行调试并快速越过 httpmodule 中的断点,它似乎只会命中一次init 方法,而eventhandler也是如此。如果我改为让它在断点处挂起几秒钟,则会多次调用init 方法(似乎这取决于我在跨过断点之前等待多长时间)。也许这可能是一些内置功能,以确保 httpmodule 已初始化并且 http 应用程序可以服务 requests ,但它似乎也可能产生灾难性后果。
这似乎是合乎逻辑的,因为它可能正在尝试完成请求,并且由于我设置了断点,它认为出现问题并尝试再次调用 init 方法?所以它可以处理请求吗?
但这是正在发生的事情,一切都很好(我只是在猜测),还是一个真正的问题?
我特别担心的是,如果某些东西使它在“生产/实时”服务器上挂起几秒钟,则会通过init添加许多事件处理程序,因此对页面的每个请求都会突然触发事件处理程序几次。
这种行为可能会迅速导致任何网站宕机。
我已经查看了用于表单身份验证的httpmodules和rolemanagermodule等的“原始”.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(及其模块)将再次尝试服务请求,导致它多次命中事件处理程序。
但似乎如果我然后跳回第一页(或另一页),只有一个HttpApplication将开始处理请求并且一切都按预期进行 - 只要我不让它在断点处挂起.
如果我让它挂在断点上,它会开始创建新的HttpApplication对象并开始添加HttpApplications(超过 1 个)来服务/处理请求(该请求已经在由当前停止在断点)。
我猜想或希望它可能是一些智能的“幕后”方式来帮助分配和处理负载和/或错误。但我不知道。我希望那里的一些人可以向我保证它很好,它应该是怎样的?