ASP.NET通过Appliaction和Session统计在人数和历史访问量

news2024/9/22 17:19:18

目录

背景:

Appliaction:

Session:

过程:

数据库:

Application_Start:

Session_Start:

Session_End:

Application_End:


背景:

事件何时激发
Application_Start在调用当前应用程序目录(或子目录)的第一个ASP.NET页面时激发
Applicaiotn_End在应用程序最后一次会话结束时激发,此外在使用Internet服务管理器管理单元停止,Web应用程序时也会激发
Application_BeginRequest在每次页面请求开始时(理论上,在加载或刷新页面)激发
Application_EndRequest在每次页面请求结束时(即每次在浏览器上执行该页面时)激发
Session_Start在每次新的会话开始时激发
Session_End在会话结束时激发

Appliaction:

Application(通常写作Applicaiton)和Session在Wweb开发中各自扮演重要的角色,它们之间既有关联也有区别

Application对象是一个应用级别的对象,主要用于存储和访问来自任何页面的变量,它表示用来保存所有用户(浏览器)共享的数据,直到Web服务器或Pc关闭为止。由于所有的用户共享一个Applicaiton对象,因此它可以用来在所有用户之间共享信息,并可以在Web应用程序运行期间持久地保持数据,如果不加以限制,所有的客户都可以访问这个对象。

Session:

存储用户信息

优点→-包含用户信息

      -在会话中跟踪和监视用户信息

      -会话期满后销毁对象

对象则与特定的用户关联,每个用户都有自己的Session对象,Session用于存储特定用户ADO会话所需的信息,主要用于弥补HTTP协议的不足,因为HTTP协议是一种无状态的协议。Session对象从用户到达某个特定的Web页开始存在,直到该用过户离开Web站点或在程序中利用代码终止某个Session为止,Session的存储是有时效性的,超过设置时间后会被服务器从内存中清除

总的来说Appliction和 Session都是ASP文件公用的对象,用于在多个网页之间保留和使用一些公用信息。它们主要区别于作用的范围和应用场景:Applicaiotn是所有用户共享的,用于全局范围内数据持久化;而Session则是针对单个用户的,用于存储特定用户的会话信息

过程:

数据库:

-- 首先创建一个数据库:  
CREATE DATABASE countpeople; -- 创建数据库  
USE countpeople; -- 转到数据库中  
  
-- 创建表  
CREATE TABLE countepeople (  
    num INT -- 新建字段  
);  
  
-- 插入一条数值为0的记录  
INSERT INTO countepeople VALUES (0);

在ASP.NE中统计在线人数和历史访问人数需要使用四个事件:Applicaiton_Start(),Application_End(),Session_Start()和Session_End();在ASP.NET应用程序启动时,会先触发Application_Start()事件,这是因为Application_Start()事件是在应用程序的全局.asax文件中定义的,并且它是在应用程序开始时被调用的特殊事件。

Application_Start:

在ASP.NET中,当应用程序启动时,会首先触发Global.asax的Applicaiotn_Start()事件,在这个事件中,我们可以增加两个Applicaiotn变量来表示整个程序的公共变量:totalCouont(用来表示总的访问量)和onlineCount(用来表示当前在线人数)

    void Application_Start(object sender, EventArgs e)
    {
       RouteConfig.RegisterRoutes(RouteTable.Routes);
       BundleConfig.RegisterBundles(BundleTable.Bundles);
       //上面两行代码,分别用于注册应用程序的路由河 资源捆绑配置,以便于管理 网站的ULR路由和静态资源文件
       SqlConnection con = new SqlConnection("server=.;database=countPeople;uid=sa;pwd=123;");
       //数据库连接对象
       con.Open();
       //打开数据库连接
       SqlCommand cmd = new SqlCommand("select * from countPeople", con);
       //创建SQL查询命令,用于执行查询数据库中countPeple表的所有内容
       int count = Convert.ToInt32(cmd.ExecuteScalar());
       //执行SQL查询命令并获得命令并获取查询结果的第一行第一列的值,即数据库中的访问人数,并将其转换为整数类型
       con.Close();
      //关闭数据库
       Application["total"] = count;
      //查询得到的访问人数存储在应用程序的Application对象中,使用名为"total"的变量表示当前在线人数
       Application["online"] = 0;  
     }
      //初始化在线人数未0,并将其存储在应用程序的Applicaiton对象中,使用名为"online"的变量来表示在线人数

Session_Start:

当每个客户端(浏览器)首次访问服务器时,会触发Session_Start事件,在这个事件中,我们需要让两个"公共变量"totalCount和onlineCount各自自增1",然后,当有多个客户端同时访问时,如果多个请求试图同时更新这些变量,就可能发生数据竞争,导致结果不准确,所以我们为了避免这种情况,我们可以使用Application.Lock()方法来锁定Application对象,确保在任何时候只有一个请求能够修改totalCount和onlineCount。当Applicaiont.Lock()被调用后,任何尝试读取或修改Applicaiont对象的操作都将被阻塞,直到Applicaiotn.UnLock()被调用。这样,就可以保证线程安全地更新这些变量。

   void Session_Start(object sender, EventArgs e)
   {
    Session.Timeout = 1;
    //通过设置Session.Timeout=1,将会话时间设置超过一分钟。这意味如果月用户在一分钟内没有活动,则其会话将过期并清除
    Application.Lock();
    //使用Application.Lock()方法锁定Applicaiton对象,以确保在同一时刻只有一个请求可以修改Applicaiton对象的状态
   //防止数据不一致的问题
    Application["total"] = (int)Application["total"] + 1;
    //尝试将Application对象中名为"total"的值(总访问量)转换为整数,然后加1,再将结果存回Applicaotn对象中
   //如果"total"键不存在或不是整数,这行代码会抛出异常
    Application["online"] = (int)Application["online"] + 1;
    //与上面类似,尝试将Applicaont对象中名为"onLine"的值(在线人数)转换未整数,然后加1,再将结果存回Application对象中
   //如果"online"键不存在或不是整数,这行代码也会抛出异常
    Application.UnLock();
    }
   //使用Applicaotn.UnLokc()方法解除对Application对象的锁定,允许其他请求修改Application对象的状态

现在,我们已经 统计出了在线人数和历史访问数量,这连个值存储在Application对象。当需要在页面上显示这些值时,我们可以直接通过访问Applicaiton["变量名"]来获取它们。我的是在Label控件上显示人数和历史记录,我建了一个Default窗体拖拽了两个控件一个lable1和label2,用来在窗体显示历史记录和在线人数,直接将Applicaiton["onLine"]的值转换未字符串并赋值给Label的Text属性;

            protected void Page_Load(object sender, EventArgs e)
            {
            this.lblTotal.Text = Application["total"].ToString();
            //历史记录
            this.lblOneLine.Text = Application["online"].ToString();
            //在线人数 
             }

Session_End:

注意一点,因为Applicaiotn对象中存储的变量值都是Object类型的,所以当我们从Application中取出值时,我们需要确保进行正确的类型转换。如果Application["onLine"]不是一个可以转换未字符串的对象,上面的代码将会抛出异常。因此,通常我们会检查该值是否存在,并确认其类型,然后再进行转换和显示,Aapplicaiton["total"也是一样]
当一个客户端(浏览器)与服务器的会话结束时,会触发Session_End事件。在这个事件中,我们不需要修改历史访问数量,但是在线人数需要减1,以反应当前活跃的会话数量减少了。在Session_End事件中,我们可以编写如下代码来更新在线人数

       void Session_End(Object sender, EventArgs e)
       {
       Application.Lock();
      //锁定Applicaiotn对象。Lock方法确保在当前线程释放锁之前,其他线程不能修改Applicaiotn对象
      //在ASP.NET中,Applicaiton对象是一个全局对象,它允许在整个Web应用程序中存储和访问数据。由于多个线程可能同时访问和修改Application对象的数据,为了避免数据不一致或竞争条件(race conditions),你要在使用它之前先锁定它。Lock方法确保了在当前线程释放锁之前,其他线程不能修改Applicaiotn对象。
      Application["online"] = (int)Application["online"] - 1;
      //它从Application对象中获取键为"online"的值,并假设这个值是一个整数(int)
      //它将这个整数值减1,然后将结果存回Application对象中,仍然使用键"online"
      //用于跟踪当前在线的用户数,每当一个会话结束时(通过Session_End事件来监测),在线用户就回减少。需要注意的是,直接进行类型转换(int)前应该检查该值是否确实存在且可以被转换为整数以避免运行时错误
      Application.UnLock();
       }
      //解锁Application对象的。一旦你完成了对Application对象的修改,就应该立即解锁它,以便其他线程可以访问和修改它。忘记解锁Application对象可能会导致性能问题,因为其他线程将被阻塞,等待锁被释放。

Application_End:

如果服务器要关闭,历史总人数我们是不是要保存,再次登录的时候历史记录人数累加起来,所以我们就要把目前Application中存储的历史访问总数更新到数据库中,在Applicaiton_End()事件中进行:

   void Application_End(Object sender, EventArgs e)
   //定义一个SqlConnection对象conn,用于与数据库进行连接。连接字符串指定了数据库服务器、数据库名称、用户名和密码
   { 
       SqlConnection con = new SqlConnection("server=.;database=countPeople;uid=sa;pwd=123;");
       //这行代码创建了一个SqlConnection对象con,用于与数据库进行连接。连接字符串指定了数据库服务器、数据库名称、用户名和密码
       con.Open();
       //这行代码打开了数据库的连接,以便后续可以执行数据库操作
       SqlCommand cmd = new SqlCommand("update  countPeople set num=" + Application["total"].ToString(), con);
       //创建一个SqlCommand对象cmd,用于执行sql语句, SQL语句是一个更新语句,将应用程序对象中存储"total"值更新到countPeople的num字段中
       cmd.ExecuteNonQuery();
       //执行了SQL更新语句,将应用程序对象存储"totle"值更新到数据库中
       con.Close();

到这里大家肯定有个疑问,假如您现在是在Visual Studio 2022中,关闭系统时,并没有触发Applicaiotn_End事件,历史记录人数并没有被写到数据库。那么该如何操作才能让Application_End事件触发呢,本人找到两种方法
第一种办法:
当你运行Visual Studio 2022的时候,你的电脑右小角又会又一个IIS EXpress的图标,选中查看所有应用程序,然后停止正在运行得程序,也可以登录IIS主界面去停止程序。

第二种办法:

当应用程序域结束时,Application_End 方法会自动执行,而不需要手动触发。但是,您可以通过模拟应用程序域重新加载的方式来测试 Application_End 方法。

在代码中手动调用 HttpRuntime.UnloadAppDomain() 方法来模拟应用程序域的重新加载,从而间接地触发 Application_End 方法执行。

详细步骤:

在 ASP.NET 项目中的 Global.asax 文件。

 Application_End 方法中添加这行代码

void Application_End(object sender, EventArgs e)
{

    System.Diagnostics.Debug.WriteLine("应用程序结束于:" + DateTime.Now.ToString());
}

在您的代码中的某个地方,调用 HttpRuntime.UnloadAppDomain() 方法来模拟应用程序域的重新加载。我是显示历史记录和在线人数得界面上,添加了一个Button按钮

protected void Button1_Click(object sender, EventArgs e)
{
    // 模拟应用程序域的重新加载
    System.Web.HttpRuntime.UnloadAppDomain();
}

运行您的应用程序,并在触发了 HttpRuntime.UnloadAppDomain() 方法的位置进行操作。您将看到在应用程序重新加载时,Application_End 方法会执行,并且其中的代码逻辑将被触发。
通过以上步骤,您可以在开发和测试环境中模拟应用程序域的重新加载,从而验证 Application_End 方法的执行情况。请记住,在生产环境中要小心谨慎,避免频繁手动触发应用程序域的重新加载。


注意:只是在服务器上停止该程序的运行才会触发Application_End()事件,重启和断电等情况并不能触发



 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1527308.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

学习笔记Day8:GEO数据挖掘-基因表达芯片

GEO数据挖掘 数据库:GEO、NHANCE、TCGA、ICGC、CCLE、SEER等 数据类型:基因表达芯片、转录组、单细胞、突变、甲基化、拷贝数变异等等 常见图表 表达矩阵 一行为一个基因,一列为一个样本,内容是基因表达量。 热图 输入数据…

AJAX——综合案例

1 Bootstrap弹框 功能&#xff1a;不离开当前页面&#xff0c;显示单独内容&#xff0c;供用户操作 步骤&#xff1a; 引入bootstrap.css和bootstrap.js准备弹框标签&#xff0c;确认结构通过自定义属性&#xff0c;控制弹框的显示和隐藏 <!DOCTYPE html> <html la…

量子计算+HPC!ORNL与Riverlane、Rigetti合作研发

内容来源&#xff1a;量子前哨&#xff08;ID&#xff1a;Qforepost&#xff09; 编辑丨慕一 编译/排版丨沛贤 1000字丨8分钟阅读 近日&#xff0c;英国量子计算初创公司Riverlane和美国量子计算公司Rigetti Computing宣布将参与由美国能源部橡树岭国家实验室&#xff08;OR…

扇区架次数动态展示

打开前端Vue项目&#xff1a;kongguan_web&#xff0c;完成前端src/components/echart/SectorFlightChart.vue页面设计&#xff0c;使用ECharts插件实现柱状图和饼状图 在src/components目录下创建echart目录&#xff0c;完成src/components/echart/SectorFlightChart.vue 的页…

【重温设计模式】观察者模式及其Java示例

观察者模式的概念和原理 在编程世界中&#xff0c;设计模式作为一种解决问题的策略&#xff0c;它的存在就如同人类语言中的成语&#xff0c;是一种经过时间考验的有效解决方案。 观察者模式就是其中一种重要的设计模式&#xff0c;它在很多场景中都有着广泛的应用。那么&…

自然语言处理: 第十七章RAG的评估技术RAGAS

论文地址&#xff1a;[2309.15217] RAGAS: Automated Evaluation of Retrieval Augmented Generation (arxiv.org) 项目地址: explodinggradients/ragas: Evaluation framework for your Retrieval Augmented Generation (RAG) pipelines (github.com) 上一篇文章主要介绍了R…

【论文阅读笔记】Split frequency attention network for single image deraining

1.论文介绍 Split frequency attention network for single image deraining 用于单幅图像去噪的分频注意力网络 Paper Code 2023年 SIVP 2.摘要 雨纹对图像质量的影响极大&#xff0c;基于数据驱动的单图像去噪方法不断发展并取得了巨大的成功。然而&#xff0c;传统的卷积…

7大结构型设计模式

结构性设计模式是软件工程中常用的一类设计模式。 作用&#xff1a;主要用于处理类或对象之间的组合以实现更灵活、可扩展和可维护的代码结构。 这些模式通常涉及到类和对象之间的静态组合关系&#xff0c;以及如何将它们组织在一起以满足特定的设计目标。 结构型模式有&#x…

git设置别名及查看别名

设置别名 git config --global alias.lg "具体的参数"git config --global alias.lg "log --dateformat:%Y/%m/%d %H:%M:%S --prettyformat:%C(yellow)%h%C(reset) %C(bold blue)%ad%C(reset) %an %C(green)%s%C(reset)"查看别名 git config --list | fi…

新能源汽车小三电系统

小三电系统 新能源电动汽车的"小三电"系统&#xff0c;一般指车载充电机(OBC)、车载 DC/DC 变换器&#xff0c;和高压直流配电盒(PDU)。一辆纯电动汽车一般配备一台OBC 和一台车载 DC/DC 变换器。OBC将外部输入的交流电转化为直流电输出给电池&#xff0c;DC/DC衔接…

数据可视化实战(二)

将每个城市在每个月份平均PM2.5绘制成折线图 import pandas as pd import matplotlib.pyplot as plt df pd.read_excel(./PM2.5.xlsx)display(df.head(10)) df.shape # (161630, 15)城市年份月份日期小时季节PM2.5露点湿度压强温度风向累计风速降水量累计降水量0北京2010112…

总结mac下解决matplotlib中文显示问题的几种方法

一、前言&#xff1a; 使⽤matplotlib画图时&#xff0c;由于matplotlib默认没有中⽂&#xff0c;显⽰中文时会出现空⽩⼩⽅块。 二、方法&#xff1a; 2.1 matplotlib中使用SimHei字体 1&#xff09;进入终端后查看matplotlib的字体路径&#xff1a; $ python >>&g…

机器学习-04-分类算法-04-支持向量机SVM

总结 本系列是机器学习课程的系列课程&#xff0c;主要介绍机器学习中分类算法&#xff0c;本篇为分类算法与SVM算法部分。 本门课程的目标 完成一个特定行业的算法应用全过程&#xff1a; 懂业务会选择合适的算法数据处理算法训练算法调优算法融合 算法评估持续调优工程化…

Qt5.14.2 深入理解Qt多线程编程,掌握线程池架构实现高效并发

在高并发的软件系统中&#xff0c;多线程编程是解决性能瓶颈和提高系统吞吐量的有效手段。作为跨平台的应用程序开发框架&#xff0c;Qt为我们提供了强大的多线程支持。本文将深入探讨Qt多线程编程的实现细节&#xff0c;并介绍线程池的设计思想&#xff0c;帮助读者彻底掌握Qt…

Pytorch常用的函数(七)空洞卷积详解

Pytorch常用的函数(七)空洞卷积详解 1 初识空洞卷积 1.1 空洞卷积与语义分割任务 语义分割面临的困境&#xff1a; 与检测模型类似&#xff0c;语义分割模型也是建立是分类模型基础上的&#xff0c;即利用CNN网络来提取特征进行分类。在CNN分类模型中&#xff0c;一般情况下…

鸿蒙开发 一 (一)、框架了解

一、UI框架 开发范式名称 语言生态 UI更新方式 适用场景 适用人群 声明式开发范式 ArkTS语言 数据驱动更新 复杂度较大、团队合作度较高的程序 移动系统应用开发人员、系统应用开发人员 类Web开发范式 JS语言 数据驱动更新 界面较为简单的程序应用和卡片 Web前端…

2025张宇考研数学基础36讲,视频百度网盘+PDF

一、张宇老师全年高数体系&#xff08;听课用书指南&#xff09; 25张宇全程&#xff1a; docs.qq.com/doc/DTmtOa0Fzc0V3WElI 复制粘贴在浏览器上打开&#xff0c;就可以看到2025张宇的全部的啦&#xff01; 一般来说我们把考研数学划分为3-4个阶段&#xff0c;分别是基础阶…

详解基于快速排序算法的qsort的模拟实现

目录 1. 快速排序 1.1 快速排序理论分析 1.2 快速排序的模拟实现 2. qsort的模拟实现 2.1 qsort的理论分析 2.2 qsort的模拟实现 qsort函数是基于快速排序思想设计的可以针对任意数据类型的c语言函数。要对qsort进行模拟实现&#xff0c;首先就要理解快速排序。 1. 快…

【物联网应用】基于云计算的智能化温室种植一体化平台

目录 第一章 作品概述 1.1. 作品名称 1.2. 应用领域 1.3.主要功能 1.4.创新性说明 第二章 需求分析 2.1 现实背景 2.2 用户群体及系统功能 2.3 竞品分析 第三章 技术方案 3.1. 硬件组成与来源 3.2. 硬件设计合理性 3.3. 硬件系统设计图 3.4. 接口的通用性与可扩展性 3.5. 代码规…

【已解决】在pycharm终端无法激活conda环境,但在cmd命令行中可以

一、问题描述 在windows下winr启动cmd命令行&#xff0c;可以成功运行conda命令并且激活环境在pycharm中打开Terminal终端&#xff0c;发现无法运行conda和pip命令&#xff0c;报错环境无法激活 无法在管道中间运行文档: D:\software\Anaconda3\condabin\conda.bat。 所在位置…