Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/320.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/url/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# HttpModule Init方法被多次调用-为什么?_C#_.net_Httpmodule_Init - Fatal编程技术网

C# HttpModule Init方法被多次调用-为什么?

C# HttpModule Init方法被多次调用-为什么?,c#,.net,httpmodule,init,C#,.net,Httpmodule,Init,我正在创建一个http模块,在调试过程中,我注意到一些起初(至少)看起来很奇怪的行为 当我在httpmodule的init方法中设置断点时,我可以看到http模块init方法被调用了好几次,尽管我只启动了网站进行调试并发出了一个请求(有时只命中1次,其他时候多达10次) 我知道我应该期望HttpApplication的几个实例正在运行,每个实例都将创建http模块,但当我请求单个页面时,它应该由单个http应用程序对象处理,因此只触发一次相关事件,但它仍然会为每个请求触发几次事件,这毫无意义——

我正在创建一个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代码……但是我的代码与这些模块使用的代码没有任何不同

我的代码看起来像这样

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当前已在断点处停止)

我猜想或希望这可能是一种智能的“幕后”方式,帮助分配和处理负载和/或错误。但我不知道。
我希望有人能向我保证它是完美的,它应该是什么样子的?

这里有一些关于你应该使用什么、什么时候以及它们如何工作的解释。

编辑:更多阅读

  • 检查HttpContext.Current.Request以查看模块的init触发的请求。可能是浏览器发送了多个请求

  • 如果您连接到IIS,请检查IIS日志,以了解在您停留在断点时是否收到任何请求


  • 多次调用
    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
        }