使用应用程序状态
可以把变量和对象直接保存到应用程序状态(Application State)中。添加到应用程序状态中的项可以被当前应用程序中任何页面内访问到。存储在应用程序状态中的项可以像应用程序的全局变量那样起作用。
在应用程序状态中创建新项: Application("myString")="Hello World!!"
然后在应用程序内任何页面都可以直接使用这一项 Application("myString")。如Response.Write(Application("myString")) ,输出内容为 “Hello World!!”。
同样可以添加其他复杂的对象,如集合、DataSet等,
Application("myDataSet")=dtDataSet
用这条语句添加了DataSet后,任何ASP.NET页面都可以从应用程序状态中直接使用MyDataSet且显示其数据。
移除方法: Application.Remove("myString")
移除所有内容:Application.Clear() 或Application.RemoveAll()
应用程序状态和同步
由于存储在应用程序状态中的项是跨页面共享的,所以就有可能产生冲突,有时会导致死锁、竞争条件或者访问障碍等一系列的问题。为了规避这些问题,可以强制对这些项进行按顺序的访问。可以通过应用程序状态的两个方法来实现:Lock和UnLock。
Lock方法锁定应用程序状态对象,因此该对象就只能由当前线程访问。
Unlock方法是释放对应用程序状态对的锁,这样其他页面就可以访问应用程序状态中的值了。
只要是在访问应用程序状态中的集合时,要么应该使用Lock和UnLock方法,要么创建线程安全的集合。
使用Global.asax文件
Application_AuthenticateRequest 在验证用户前产生
Application_AuthorizeRequest 在授权用户前产生
Application_BeginRequest 在每个对服务器的请求产生
Application_End 在所有应用程序实例结束后立即产生
Application_EndRequest 在每个对服务器的请求结束时产生
Application_Errow 在应用程序中的未处理错误产生
Application_PreSendRequestContent 在发送内容到浏览器之前产生
Application_PreSendRequestHeaders 在发送Http头到浏览器之前产生
Application_Start 在创建第一个应用程序结束后立即产生。该事件只会产生一次。
DisPose 在单个应用程序实例结束之前立即产生
Init 在创建每个应用程序实例后立即产生。该事件可能会产生多次。
如果在Global.asax文件中一个熟悉的属性或方法不起作用,那么就应当那个立即替换使用Context对象来试试调用该方法或属性。
Application_Start事件在应用程序的生命周期中只产生一次,在在初始化全局变量挺合适的。
Sub Application_Start()
Sub Application_Start
dim conn as SqlConnection
dim strSql as string
dim sda as SqlDataAdapter
dim ds as DataSet
conn=new SqlConnection("server=.;uid=sa;pwd=sa;database=northwind")
strSql="select * from Products"
sda=new SqlDataAdapter(strSql,conn)
ds=new DataSet()
sda.Fill(ds,"Products")
Context.Cache("Products")=ds
End Sub
dim conn as SqlConnection
dim strSql as string
dim sda as SqlDataAdapter
dim ds as DataSet
conn=new SqlConnection("server=.;uid=sa;pwd=sa;database=northwind")
strSql="select * from Products"
sda=new SqlDataAdapter(strSql,conn)
ds=new DataSet()
sda.Fill(ds,"Products")
Context.Cache("Products")=ds
End Sub
Asp.net框架是用应用程序的实例池来处理连接到服务器的每个请求。当有请求连进来时,就为该请求分配一个应用程序实例。在创建任何一个应用程序实例后,就立即产生Init时间。
访问Web站点的第一个页面是就同时产生Application和Init时间,Application_Star事件在应用程的生命周期内并不会再次产生,而Init事件则可以产生多次。
可以用Init事件来初始化需要在特定应用程序实例的生命周期内使用的任何变量或对象。如果对局部变量赋了值,那么对这变量也会在跨多次请求时保持其值。
自动添加一个随机的广告条到每个页面的底部。
Global.asax
dim dtblBannerAdsas DataTable
Override Sub Init() Sub Init()Sub Init()sub Init()
dim ds=new DataSet
ds.ReadXml(Server.Mappath("adFile.xml"))
dtblBannerAds=ds.Tables(0)
End Sub
Sub Application_PreSendRequestContent()Sub Application_PreSendRequestContent()Sub Application_PreSendRequestContent()Sub Application_PreSendRequestContent
dim str as string
dim objRand as Random
dim drowSelectedAd as DataRow
objRan=New Random()
drowSelectedAd=dtbBannerAds.Rows.Rows(objRan.Next(dtblBannerAds.Rows.Count))
strPageFooter="<hr><a href=" & drowSelectedAd("NavigateUrl")
strpageFooter &= "><img src=" & drowSelectedAd("ImageUrl")
strPageFooter &="></a>"
Reponse.Write(strPageFooter)
End Sub
dim dtblBannerAdsas DataTable
Override Sub Init() Sub Init()Sub Init()sub Init()
dim ds=new DataSet
ds.ReadXml(Server.Mappath("adFile.xml"))
dtblBannerAds=ds.Tables(0)
End Sub
Sub Application_PreSendRequestContent()Sub Application_PreSendRequestContent()Sub Application_PreSendRequestContent()Sub Application_PreSendRequestContent
dim str as string
dim objRand as Random
dim drowSelectedAd as DataRow
objRan=New Random()
drowSelectedAd=dtbBannerAds.Rows.Rows(objRan.Next(dtblBannerAds.Rows.Count))
strPageFooter="<hr><a href=" & drowSelectedAd("NavigateUrl")
strpageFooter &= "><img src=" & drowSelectedAd("ImageUrl")
strPageFooter &="></a>"
Reponse.Write(strPageFooter)
End Sub
在Init子程序中,从一个名为AdFile.xml的XML文件加载了一个广告条的列表到DataSet中,这个子程序只对每个应用程序实例运行一次。
接着,在AP_PresendRequestContent子程序中,从DataSet中随机选择一个广告并发送到浏览器。PreSendRequestContent子程序正好是在要发送内容到浏览器之前执行。因此在该子程序中输出的内容就肯定是显示在页面的底部。