Можно ли использовать свойство Application класса HttpApplication для вычисления текущих активных пользователей?

Я использую следующий код на странице Global.aspx веб-форм ASP.NET для подсчета количества текущих активных пользователей. Это работает, когда я провожу локальное тестирование.

Понимание заключается в том, что приложение является переменной уровня приложения и может быть доступно на уровне приложения. Таким образом, значение, сохраненное в одном сеансе, будет доступно в других сеансах.

      <%@ 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>

Но при переходе по этой ссылке https://docs.microsoft.com/en-us/dotnet/api/system.web.httpapplication?redirectedfrom=MSDN&amp;amp;view=netframework-4.8 говорится, что переменные-члены могут использоваться для хранения данные запроса.

Основываясь на этом заявлении и приведенном ниже полном абзаце, может быть несколько экземпляров HttpApplication для одного приложения, если нет, приложение будет очень медленным, поскольку один экземпляр HttpApplication может обрабатывать только один запрос в один момент времени.

Из-за этого каждое HttpApplication будет иметь свою собственную переменную приложения, и счетчик будет сохранен на уровне HttpApplication.

Экземпляры класса HttpApplication создаются в инфраструктуре ASP.NET, а не непосредственно пользователем. Один экземпляр класса HttpApplication используется для обработки множества запросов за время своего существования. Однако он может обрабатывать только один запрос за раз. Таким образом, переменные-члены могут использоваться для хранения данных для каждого запроса.

Приложение генерирует события, которые могут обрабатываться пользовательскими модулями, реализующими интерфейс IHttpModule, или кодом обработчика событий, определенным в файле Global.asax. Пользовательские модули, реализующие интерфейс IHttpModule, можно поместить в папку App_Code или в DLL в папке Bin.

Итак, чтобы получить точное количество без каких-либо шансов просчета, должен ли я использовать статические переменные?

1 ответ

Я считаю, что ваш код будет работать правильно, если вы используете состояние сеанса InProc и не работаете в веб-ферме.

Как ни странно, слово «приложение» может иметь три разных значения:

  1. Ваше веб-приложение (то есть весь веб-сайт)
  2. Один из нескольких экземпляров HttpApplication , которые обслуживают запросы к вашему веб-приложению .
  3. Свойство HttpApplication.Application _

Когда в документации говорится, что свойство Application возвращает «текущее состояние приложения», имеется в виду ваше веб-приложение, а не отдельный экземпляр HttpApplication.

Это правда, что если вы добавите переменную-член в свой глобальный класс (который наследуется от HttpApplication), то переменная-член не будет совместно использоваться экземплярами HttpApplication. Но свойство Application является особенным: оно возвращает один и тот же объект HttpApplicationState независимо от того, какой экземпляр HttpApplication используется для доступа к свойству. Следовательно, любые значения, которые вы добавляете через свойство Application, будут общими для всех экземпляров HttpApplication. (И именно поэтому вы должны вызывать Lock и UnLock для синхронизации доступа; вам не нужно было бы делать это, если бы объект HttpApplicationState не был общим.)

Другие вопросы по тегам