HttpApplication class 的 Application 属性 可以用来计算当前活跃用户数吗?

Can Application property of HttpApplication class be used to calculate current Active Users?

我在 ASP.NET 网络表单 Global.aspx 页面中使用以下代码来计算当前活跃用户的数量。当我进行本地测试时它确实有效。

理解是Application是一个Application-level变量,可以在应用层访问。因此存储在一个会话中的值将在其他会话中可用。

<%@ Application Language="C#" %>  
  
<script runat="server">  
  
    void Application_Start(object sender, EventArgs e)   
    {  
        // Code that runs on application startup  
        Application["TotalOnlineUsers"] = 0;  
    }  
      
    void Application_End(object sender, EventArgs e)   
    {  
        //  Code that runs on application shutdown  
  
    }  
          
    void Application_Error(object sender, EventArgs e)   
    {   
        // Code that runs when an unhandled error occurs  
  
    }  
  
    void Session_Start(object sender, EventArgs e)   
    {  
        // Code that runs when a new session is started  
        Application.Lock();  
        Application["TotalOnlineUsers"] = (int)Application["TotalOnlineUsers"] + 1;  
        Application.UnLock();  
    }  
  
    void Session_End(object sender, EventArgs e)   
    {  
        // Code that runs when a session ends.   
        // Note: The Session_End event is raised only when the sessionstate mode  
        // is set to InProc in the Web.config file. If session mode is set to StateServer   
        // or SQLServer, the event is not raised.  
        Application.Lock();  
        Application["TotalOnlineUsers"] = (int)Application["TotalOnlineUsers"] - 1;  
        Application.UnLock();  
    }  
         
</script>

但是在查看这个 link https://docs.microsoft.com/en-us/dotnet/api/system.web.httpapplication?redirectedfrom=MSDN&view=netframework-4.8 时,它说 成员变量可用于存储每个请求的数据 .

根据此声明和下面的完整段落,单个应用程序可以有多个 HttpApplication 实例,否则应用程序将非常慢,因为一个 HttpApplication 实例在一个时间点只能处理一个请求

因此,每个 HttpApplication 都有自己的 Application 变量,计数将保存在 HttpApplication 级别。

Instances of the HttpApplication class are created in the ASP.NET infrastructure, not by the user directly. One instance of the HttpApplication class is used to process many requests in its lifetime. However, it can process only one request at a time. Thus, member variables can be used to store per-request data.

An application raises events that can be handled by custom modules that implement the IHttpModule interface or by event handler code that is defined in the Global.asax file. Custom modules that implement the IHttpModule interface can be put in the App_Code folder or in a DLL in the Bin folder.

那么,为了获得准确的计数而不会计算错误,我应该使用静态变量吗?

我相信您的代码会正常工作,假设您使用的是 InProc 会话状态并且 运行 不在 Web 场中。

令人困惑的是,“应用程序”这个词可以有三种不同的含义:

  1. 您的 Web 应用程序(即整个网站)
  2. 为您的 Web 应用程序提供请求的多个 HttpApplication 实例之一
  3. HttpApplication.Application属性

当文档说应用程序 属性 returns“应用程序的当前状态”时,它表示您的 Web 应用程序,而不是 个人HttpApplication 实例。

的确,如果 向你的全局 class 添加一个成员变量(它继承自 HttpApplication),那么该成员变量将不会在 HttpApplication 之间共享实例。但是 Application 属性 是特殊的:它 returns 相同的 HttpApplicationState 对象,无论您使用哪个 HttpApplication 实例来访问 属性。因此,您通过 Application 属性 添加的任何值都将在所有 HttpApplication 实例之间共享。 (这就是为什么必须调用 Lock 和 UnLock 来同步访问;如果 HttpApplicationState 对象未共享,则不需要这样做。)