C# HttpModule Init方法被多次调用-为什么?
我正在创建一个http模块,在调试过程中,我注意到一些起初(至少)看起来很奇怪的行为 当我在httpmodule的init方法中设置断点时,我可以看到http模块init方法被调用了好几次,尽管我只启动了网站进行调试并发出了一个请求(有时只命中1次,其他时候多达10次) 我知道我应该期望HttpApplication的几个实例正在运行,每个实例都将创建http模块,但当我请求单个页面时,它应该由单个http应用程序对象处理,因此只触发一次相关事件,但它仍然会为每个请求触发几次事件,这毫无意义——除了它必须在该httpApplication中添加了几次之外——这意味着每次调用的都是同一个httpmodule init方法,而不是每次到达断点时都创建一个新的http应用程序(请参阅底部的代码示例等) 这里可能出了什么问题?是因为我正在调试并在http模块中设置断点吗 它已经注意到,如果我启动网站进行调试并快速跨过httpmodule中的断点,它只会命中init方法一次,eventhandler也是如此。如果我让它在断点处挂起几秒钟,init方法会被调用几次(这似乎取决于我在跨过断点之前等待的时间)。这可能是某种内置功能,以确保httpmodule已初始化,http应用程序可以为请求提供服务,但也可能会造成灾难性后果 这似乎是合乎逻辑的,因为它可能正在尝试完成请求,而且由于我设置了断点,它认为出现了问题,并尝试再次调用init方法?它是否能够处理请求 但这是正在发生的事情,一切都好吗(我只是猜测),还是真的有问题 我特别关心的是,如果有什么东西使它挂起在“production/live”服务器上几秒钟,就会通过init添加许多事件处理程序,因此对页面的每个请求都会突然触发eventhandler数次 这种行为会很快使任何网站瘫痪 我已经查看了用于formsauthentication和RoleManager模块等的HTTPM模块的“原始”.net代码……但是我的代码与这些模块使用的代码没有任何不同 我的代码看起来像这样C# HttpModule Init方法被多次调用-为什么?,c#,.net,httpmodule,init,C#,.net,Httpmodule,Init,我正在创建一个http模块,在调试过程中,我注意到一些起初(至少)看起来很奇怪的行为 当我在httpmodule的init方法中设置断点时,我可以看到http模块init方法被调用了好几次,尽管我只启动了网站进行调试并发出了一个请求(有时只命中1次,其他时候多达10次) 我知道我应该期望HttpApplication的几个实例正在运行,每个实例都将创建http模块,但当我请求单个页面时,它应该由单个http应用程序对象处理,因此只触发一次相关事件,但它仍然会为每个请求触发几次事件,这毫无意义——
public void Init(HttpApplication应用程序)
{
if(社区身份验证集成.IsEnabled)
{
FormsAuthenticationModule FormsAuthenticationModule=(FormsAuthenticationModule)app.Modules[“FormsAuthentication”];
formsAuthModule.Authenticate+=新的FormsAuthenticationEventHandler(this.OnAuthenticate);
}
}
下面是一个示例,它是如何在.NET framework的RoleManager模块中完成的:
public void Init(HttpApplication应用程序)
{
如果(已启用角色)
{
app.PostAuthenticateRequest+=新事件处理程序(this.oneter);
app.EndRequest+=新的EventHandler(this.OnLeave);
}
}
有人知道发生了什么事吗
(我只是希望有人能告诉我为什么会发生这种情况,并向我保证一切都很好):)
更新: 我试图缩小问题的范围,到目前为止,我发现被调用的init方法总是在http模块的一个新对象上(与我之前的想法相反) 对于第一个请求(启动站点时),所有创建的HttpApplication对象及其模块都试图为第一个请求提供服务,因此都命中了正在添加的eventhandler。 我真的不明白为什么会这样 如果我请求另一个页面,所有创建的HttpApplication(及其模块)将再次尝试为请求提供服务,导致它多次命中eventhandler 但是,如果我跳回第一页(或另一页),似乎只有一个http应用程序会开始处理请求,并且一切都如预期的那样——只要我不让它挂在断点上 如果我让它挂起在断点处,它将开始创建新的HttpApplication对象,并开始添加HttpApplication(超过1个)来服务/处理请求(该请求已由HttpApplication提供服务,而HttpApplication当前已在断点处停止) 我猜想或希望这可能是一种智能的“幕后”方式,帮助分配和处理负载和/或错误。但我不知道。
我希望有人能向我保证它是完美的,它应该是什么样子的?这里有一些关于你应该使用什么、什么时候以及它们如何工作的解释。 编辑:更多阅读
多次调用
Init()
方法是正常的。当应用程序启动时,ASP.NET工作进程将实例化它认为需要的任意多个HttpApplication
对象,然后它将对它们进行池化(例如,将它们重新用于新请求,类似于数据库连接池)
现在,对于每个HttpApplication
对象,它还将实例化每个注册的IHttpModule
的一个副本,并多次调用Init方法
private static bool HasAppStarted = false;
private readonly static object _syncObject = new object();
public void Init(HttpApplication context)
{
if (!HasAppStarted)
{
lock (_syncObject)
{
if (!HasAppStarted)
{
// Run application StartUp code here
HasAppStarted = true;
}
}
}
}
public class TestModule :IHttpModule
{
#region IHttpModule Members
public void Dispose()
{
}
public void Init(HttpApplication context)
{
context.BeginRequest += new EventHandler(context_BeginRequest);
context.EndRequest += new EventHandler(context_EndRequest);
}
void context_EndRequest(object sender, EventArgs e)
{
HttpApplication app = sender as HttpApplication;
app.CompleteRequest();
app.Dispose();
}
void context_BeginRequest(object sender, EventArgs e)
{
//your code here
}
#endregion
}