C#与.NET程序员面试宝典 2.1.3 面试题3:说明ASP.NET的Application特性
这个问题的回答体现了应聘者在BS结构系统方面的编程经验,通常情况下,Application不会被程序员频繁地使用,但在一些特殊场合下Application会被经常地用到。读者需要掌握Application的概念,以及一些常用的Application特性。
【出现频率】★★★★
【关键考点】
Application概念
Application特性
【考题分析】
Application是用来保存所有用户共用的信息,在ASP时代,如果要保存的数据在应用程序生存期内不会或者很少发生改变,那么使用Application是理想的选择。但是在ASP.NET开发环境中,程序员通常把类似的配置数据放在Web.config中。如果要使用Application的话,要注意的是所有的写操作都要在Global.asax文件中的Application_OnStart事件中完成。如以下示例代码所示:
/*下面的代码在Global.asax文件中设置*/
Application.Lock(); //将Application对象加锁操作。
Application[“UserID”]=”Hello kitty”; //将Hello kitty值赋值给Application[“UserID”]对象
Application.Unlock(); ///将Application对象解锁
以下示例代码是在页面中调用Application,如下所示:
/*在Webpage中调用Application对象,请参考下面的用法。*/
String UserName=Application[“UserID”].ToString()
注意:尽管可以使用Application.Lock()避免冲突,但是它串行化了对Application的请求,会产生严重的性能瓶颈。因此,仍应尽量避免使用Application保存大数据量信息。
Application具备以下4个特性:
信息量大小为任意大小
应用于整个应用程序/所有用户
保存在服务器端
作用域和保存时间是在整个应用程序的生命期
如果在应用程序中使用Application对象,一个需要考虑的问题是任何写操作都要在Application_OnStart事件中完成。尽管使用Application.Lock和Applicaiton.Unlock方法来避免写操作的同步,但是由于它串行化了对Application对象的请求,当网站访问量大的时候会产生严重的性能瓶颈,因此最好不要用此对象保存大的数据集合。下面举一个在线用户统计的例子来说明这个问题:
using System;
using System.Collections;
using System.ComponentModel;
using System.Web;
using System.Web.SessionState;
using System.IO;
public class Global : System.Web.HttpApplication // Global 的摘要说明。
{
private System.ComponentModel.IContainer components = null; //必需的设计器变量。
private FileStream fStream;
private StreamReader reader; //读字符流
private StreamWriter writer; //写字符流
public Global()
{
InitializeComponent(); //加载组件的已编译的页
}
protected void Application_Start(Object sender, EventArgs e)
{
Application["CurrentUser"]=0; //初始化为0
//文件不存在,创建文件
fStream = File.Open(Server.MapPath("counts.text"),FileMode.OpenOrCreate);
reader = new StreamReader(fStream); //要读取的完整路径
//从当前流中读取一行字符并将数据作为字符串返回
Application["AllUser"] = Convert.ToInt32(reader.ReadLine());
reader.Close();/ //关闭流
}
//当用户访问网站时,在线用户+1,总访问数+1
protected void Session_Start(Object sender, EventArgs e)
{
Application.Lock(); //同步,避免同时写入
Application["CurrentUser"] =(int)Application["CurrentUser"]+ 1; //总在线用户数
//访问网站的总用户数
Application["AllUser"] =(int)Application["AllUser"]+ 1;
fStream = new FileStream(Server.MapPath("counts.text"),
FileMode.OpenOrCreate,FileAccess.ReadWrite);
//实现一个写入流,使其以一种特定的编码向流中写入字符
writer = new StreamWriter(fStream);
//把访问网站的总用户数再次写入到文件
writer.WriteLine(Application["AllUser"].ToString());
writer.Close(); //关闭写入流
Application.UnLock(); //同步结束
}
//当前用户退出网站时,在线用户数量-1
protected void Session_End(Object sender, EventArgs e)
{
Application.Lock();
Application["CurrentUser"] =(int)Application["CurrentUser"] - 1; //总在线用户数量-1
Application.UnLock();
}
WebPage.ASPX页面的示例代码如下:
private void Page_Load(object sender, System.EventArgs e)
{
this.Label1.Text = "当前站点的用户数:" + Application["CurrentUser"].ToString();
this.Label2.Text ="访问过站点的总用户数:" + Application["AllUser"].ToString();
}
【答案】
Application对象在实际网络开发中的用途就是记录整个网络的信息,在给定的应用程序的多有用户之间共享信息,并在服务器运行期间持久的保存数据。Application对象具备控制访问应用层数据的方法,并可用于在应用程序启动和停止时触发过程的事件。