ASP.NET 2.0 缓存清除

时间:2021-07-20 00:58:02

最近在学习ASP.NET 2.0,昨天看到了“应用程序数据缓存”中的“缓存依赖”章节,根据书上例子需要实现的功能,自己先按自己的思路编写了一个程序。在调试的过程中发现了一个有关缓存清除的问题。以下是我实现的过程:

  1. 通过vs.net 2005建立一个网站项目,然后在其中建立一个新的页面,取名为“CacheDependency.aspx”;
  2. 在App_Data文件夹中建立一个XML文件,用于页面显示的数据源,取名为Computer.xml。XML文件内容如下:
ASP.NET 2.0 缓存清除< hardware >
ASP.NET 2.0 缓存清除  
< item  choice ="Intel"  price ="1000"  url ="http://www.ibm.com"   />
ASP.NET 2.0 缓存清除  
< item  choice ="AMD"  price ="850"  url ="http://www.amd.com.cn"   />
ASP.NET 2.0 缓存清除  
< item  choice ="Microsoft"  price ="1000"  url ="http://www.microsoft.com.cn/msdn/"   />
ASP.NET 2.0 缓存清除
</ hardware >

           很容易理解,这里显示的是有关计算机的信息,每条记录中包含3个属性,分别为提供商名称、价格、网站。

      3.  在CacheDependency.aspx页面中添加如下控件(均为服务器控件):

序号

控件类型

控件ID

说明信息

1

GridView

GridView1

用于显示数据源的信息。

2

TextBox

TextBox1

用于填写新的提供商名称。

3

TextBox

TextBox2

用于填写新的价格。

4

TextBox

TextBox3

用于填写新的网址(URL)。

5

Button

Button1

用于触发更新XML数据源的过程。

6

Label

Label1

用于在缓存(Cache)清除时,显示提示信息和清除原因。

     界面设计如图:

        4. 在页面后台代码中添加如下代码,如下图所示:

ASP.NET 2.0 缓存清除Imports  System.IO
ASP.NET 2.0 缓存清除
Imports  System.Data
ASP.NET 2.0 缓存清除
Imports  System.Xml
ASP.NET 2.0 缓存清除
ASP.NET 2.0 缓存清除ASP.NET 2.0 缓存清除
Partial   Class CacheDependency Class CacheDependency
ASP.NET 2.0 缓存清除    
Inherits System.Web.UI.Page
ASP.NET 2.0 缓存清除    
Private Const strFilePath As String = "C:Documents and Settings ujunMy DocumentsVisual Studio 2005ASPDotNET2App_DataComputer.xml"
ASP.NET 2.0 缓存清除    
Private removedReason As String
ASP.NET 2.0 缓存清除
ASP.NET 2.0 缓存清除    
'从XML文件中读取数据,并将包含数据的DataTable进行返回;
ASP.NET 2.0 缓存清除ASP.NET 2.0 缓存清除
    Public Function LoadXMLFile()Function LoadXMLFile() As DataTable
ASP.NET 2.0 缓存清除        
If (File.Exists(strFilePath) = TrueThen
ASP.NET 2.0 缓存清除            
Dim ds As New DataSet
ASP.NET 2.0 缓存清除            ds.ReadXml(strFilePath)
ASP.NET 2.0 缓存清除            
Return (ds.Tables(0))
ASP.NET 2.0 缓存清除        
Else
ASP.NET 2.0 缓存清除            
Me.MsgBox("作为数据源的XML文件不存在!请检查。")
ASP.NET 2.0 缓存清除            
Return (Nothing)
ASP.NET 2.0 缓存清除        
End If
ASP.NET 2.0 缓存清除    
End Function

ASP.NET 2.0 缓存清除
ASP.NET 2.0 缓存清除    
'根据DataTable中的内容生成缓存;
ASP.NET 2.0 缓存清除ASP.NET 2.0 缓存清除
    Public Sub UpdateCache()Sub UpdateCache(ByVal dtComputerInfo As DataTable)
ASP.NET 2.0 缓存清除        
Dim dep As New System.Web.Caching.CacheDependency(strFilePath, DateTime.Now)
ASP.NET 2.0 缓存清除        Cache.Insert(
"computerInfo", dtComputerInfo, dep, DateTime.MaxValue, TimeSpan.Zero, CacheItemPriority.Default, New CacheItemRemovedCallback(AddressOf CacheItemRemoved))
ASP.NET 2.0 缓存清除    
End Sub

ASP.NET 2.0 缓存清除
ASP.NET 2.0 缓存清除    
'根据文本框的输入更新XML文件;
ASP.NET 2.0 缓存清除ASP.NET 2.0 缓存清除
    Public Sub ModifyXMLFile()Sub ModifyXMLFile()
ASP.NET 2.0 缓存清除        
If (File.Exists(strFilePath) = TrueThen
ASP.NET 2.0 缓存清除            
Dim dtXMLFile As DataTable = Me.LoadXMLFile()
ASP.NET 2.0 缓存清除
ASP.NET 2.0 缓存清除            
If (Not dtXMLFile Is NothingThen
ASP.NET 2.0 缓存清除                
Dim dr As DataRow = dtXMLFile.NewRow
ASP.NET 2.0 缓存清除                
'如果TextBox中为空,那么替换空字符串(String.Empty)的默认值;
ASP.NET 2.0 缓存清除
                Dim defaultValue As String = "--"
ASP.NET 2.0 缓存清除
ASP.NET 2.0 缓存清除                
If (TextBox1.Text <> String.Empty) Then
ASP.NET 2.0 缓存清除                    dr.Item(
"choice"= TextBox1.Text
ASP.NET 2.0 缓存清除                
Else
ASP.NET 2.0 缓存清除                    dr.Item(
"choice"= defaultValue
ASP.NET 2.0 缓存清除                
End If
ASP.NET 2.0 缓存清除
ASP.NET 2.0 缓存清除                
If (TextBox2.Text <> String.Empty) Then
ASP.NET 2.0 缓存清除                    dr.Item(
"price"= TextBox2.Text
ASP.NET 2.0 缓存清除                
Else
ASP.NET 2.0 缓存清除                    dr.Item(
"price"= defaultValue
ASP.NET 2.0 缓存清除                
End If
ASP.NET 2.0 缓存清除
ASP.NET 2.0 缓存清除                
If (TextBox3.Text <> String.Empty) Then
ASP.NET 2.0 缓存清除                    dr.Item(
"url"= TextBox3.Text
ASP.NET 2.0 缓存清除                
Else
ASP.NET 2.0 缓存清除                    dr.Item(
"url"= defaultValue
ASP.NET 2.0 缓存清除                
End If
ASP.NET 2.0 缓存清除
ASP.NET 2.0 缓存清除                dtXMLFile.Rows.Add(dr)
ASP.NET 2.0 缓存清除                
'通过文件流,重新向XML文件中写入新的数据源内容;
ASP.NET 2.0 缓存清除
                Dim fs As New FileStream(strFilePath, FileMode.Open, FileAccess.Write, FileShare.ReadWrite)
ASP.NET 2.0 缓存清除                dtXMLFile.WriteXml(fs)
ASP.NET 2.0 缓存清除                fs.Close()
ASP.NET 2.0 缓存清除
ASP.NET 2.0 缓存清除                
'重新绑定GridView
ASP.NET 2.0 缓存清除
                Me.BoundGridView(dtXMLFile)
ASP.NET 2.0 缓存清除                
'Cache.Remove("computerInfo")
ASP.NET 2.0 缓存清除
                '由于缓存(Cache)以来的XML文件的内容发生了变化,Cache将被清除,
ASP.NET 2.0 缓存清除
                '这里需要通过调用此函数来重建缓存和缓存依赖项;
ASP.NET 2.0 缓存清除
                Me.UpdateCache(dtXMLFile)
ASP.NET 2.0 缓存清除            
Else
ASP.NET 2.0 缓存清除                
Me.MsgBox("dtXMLFile为空(Nothing)")
ASP.NET 2.0 缓存清除            
End If
ASP.NET 2.0 缓存清除        
Else
ASP.NET 2.0 缓存清除            
Me.MsgBox("作为数据源的XML文件不存在!请检查。")
ASP.NET 2.0 缓存清除            
Return
ASP.NET 2.0 缓存清除        
End If
ASP.NET 2.0 缓存清除    
End Sub

ASP.NET 2.0 缓存清除
ASP.NET 2.0 缓存清除    
'用于弹出提示窗口;
ASP.NET 2.0 缓存清除ASP.NET 2.0 缓存清除
    Public Sub MsgBox()Sub MsgBox(ByVal message As String)
ASP.NET 2.0 缓存清除        ClientScript.RegisterStartupScript(ClientScript.GetType(), 
"reminderInfo", message)
ASP.NET 2.0 缓存清除    
End Sub

ASP.NET 2.0 缓存清除
ASP.NET 2.0 缓存清除    
'缓存(Cache)清除时的回调函数(CallBack),在页面中显示缓存清除的原因;
ASP.NET 2.0 缓存清除ASP.NET 2.0 缓存清除
    Private Sub CacheItemRemoved()Sub CacheItemRemoved(ByVal key As StringByVal value As ObjectByVal removeReason As CacheItemRemovedReason)
ASP.NET 2.0 缓存清除        Label1.Text 
= "移除Cache项的原因是: " & removeReason.ToString()
ASP.NET 2.0 缓存清除    
End Sub

ASP.NET 2.0 缓存清除
ASP.NET 2.0 缓存清除    
'将GridView控件绑定到数据源以显示数据源信息;
ASP.NET 2.0 缓存清除ASP.NET 2.0 缓存清除
    Private Sub BoundGridView()Sub BoundGridView(ByVal dtDataSource As DataTable)
ASP.NET 2.0 缓存清除        
If (Not dtDataSource Is NothingThen
ASP.NET 2.0 缓存清除            GridView1.DataSource 
= dtDataSource
ASP.NET 2.0 缓存清除            GridView1.DataBind()
ASP.NET 2.0 缓存清除        
End If
ASP.NET 2.0 缓存清除    
End Sub

ASP.NET 2.0 缓存清除
ASP.NET 2.0 缓存清除    
'页面载入函数;判断是否存在缓存,如果存在缓存就直接通过将GridView绑定到缓存数据来显示信息;
ASP.NET 2.0 缓存清除
    '如果不存在缓存则通过读取XML文件内容,重新建立缓存;
ASP.NET 2.0 缓存清除ASP.NET 2.0 缓存清除
    Protected Sub Page_Load()Sub Page_Load(ByVal sender As ObjectByVal e As System.EventArgs) Handles Me.Load
ASP.NET 2.0 缓存清除        
If (Not Page.IsPostBack) Then
ASP.NET 2.0 缓存清除            
Dim dtDataSource As DataTable
ASP.NET 2.0 缓存清除            
If (Cache("computerInfo"Is NothingThen
ASP.NET 2.0 缓存清除                dtDataSource 
= Me.LoadXMLFile()
ASP.NET 2.0 缓存清除                
Me.UpdateCache(dtDataSource)
ASP.NET 2.0 缓存清除            
Else
ASP.NET 2.0 缓存清除                dtDataSource 
= CType(Cache("computerInfo"), DataTable)
ASP.NET 2.0 缓存清除            
End If
ASP.NET 2.0 缓存清除
ASP.NET 2.0 缓存清除            
Me.BoundGridView(dtDataSource)
ASP.NET 2.0 缓存清除        
End If
ASP.NET 2.0 缓存清除    
End Sub

ASP.NET 2.0 缓存清除
ASP.NET 2.0 缓存清除    
'触发XML修改的按钮响应函数;
ASP.NET 2.0 缓存清除ASP.NET 2.0 缓存清除
    Protected Sub Button1_Click()Sub Button1_Click(ByVal sender As ObjectByVal e As System.EventArgs) Handles Button1.Click
ASP.NET 2.0 缓存清除        
Me.ModifyXMLFile()
ASP.NET 2.0 缓存清除    
End Sub

ASP.NET 2.0 缓存清除
End Class

这里需要注意的就是上面代码被注释掉的"Cache.Remove("computerInfo")"这一句。当不使用这句代码的时候,如果你使用代码,你会发现Label1中显示Cache被清除的信息是随即的,也就是可能你通过修改XML文件改变缓存依赖项从而触发了Cache失效清除,但是清除可能不是立刻执行的。如果对代码进行调试,那么你会发现作为Cache清除时的回调函数"CacheItemRemoved"也不是每次执行,而且即便是执行也是随即的,不是一定在执行到某一句后就会触发。这里就说明一个问题Cache的清除就和GC的过程一样是不可控制的。至于是不是就是使用GC来回收,感觉上很有可能,但是还没有确认。后来再去看书的时候,发现作者其实为什么在这里显式的调用Cache.Remove方法也做出了解释,“Cache.Remove方法在此似乎多余,但是由于本实例需要显示缓存对象移除的原因,因此,需要实现CacheItemRemoved方法。该方法由CacheItemRemovedCallback委托定义,其调用的时候必须等到调用Remove方法时,所以这里采用显式调用的方法,虽然从缓存清除的功能上确实多余,但是为了保证每次都在Label1中显示Cache清除的信息这句代码还是必要的。”

P.S. 到了这里说点别的,如果有编程的基础,那么最好是先自己实现例子需要实现的功能,然后再和提供的例子程序进行对比。这样往往可以发现一些仅仅就是看看代码,或者直接运行一下例子程序不能发现的细节问题。^_^