关闭

ASP.NET 2.0 缓存清除

1154人阅读 评论(0) 收藏 举报

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

  1. 通过vs.net 2005建立一个网站项目,然后在其中建立一个新的页面,取名为“CacheDependency.aspx”;
  2. 在App_Data文件夹中建立一个XML文件,用于页面显示的数据源,取名为Computer.xml。XML文件内容如下:
<hardware>
  
<item choice="Intel" price="1000" url="http://www.ibm.com" />
  
<item choice="AMD" price="850" url="http://www.amd.com.cn" />
  
<item choice="Microsoft" price="1000" url="http://www.microsoft.com.cn/msdn/" />
</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. 在页面后台代码中添加如下代码,如下图所示:

Imports System.IO
Imports System.Data
Imports System.Xml

Partial Class CacheDependency
    
Inherits System.Web.UI.Page
    
Private Const strFilePath As String = "C:Documents and Settings ujunMy DocumentsVisual Studio 2005ASPDotNET2App_DataComputer.xml"
    
Private removedReason As String

    
'从XML文件中读取数据,并将包含数据的DataTable进行返回;
    Public Function LoadXMLFile() As DataTable
        
If (File.Exists(strFilePath) = TrueThen
            
Dim ds As New DataSet
            ds.ReadXml(strFilePath)
            
Return (ds.Tables(0))
        
Else
            
Me.MsgBox("作为数据源的XML文件不存在!请检查。")
            
Return (Nothing)
        
End If
    
End Function


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


    
'根据文本框的输入更新XML文件;
    Public Sub ModifyXMLFile()
        
If (File.Exists(strFilePath) = TrueThen
            
Dim dtXMLFile As DataTable = Me.LoadXMLFile()

            
If (Not dtXMLFile Is NothingThen
                
Dim dr As DataRow = dtXMLFile.NewRow
                
'如果TextBox中为空,那么替换空字符串(String.Empty)的默认值;
                Dim defaultValue As String = "--"

                
If (TextBox1.Text <> String.Empty) Then
                    dr.Item(
"choice"= TextBox1.Text
                
Else
                    dr.Item(
"choice"= defaultValue
                
End If

                
If (TextBox2.Text <> String.Empty) Then
                    dr.Item(
"price"= TextBox2.Text
                
Else
                    dr.Item(
"price"= defaultValue
                
End If

                
If (TextBox3.Text <> String.Empty) Then
                    dr.Item(
"url"= TextBox3.Text
                
Else
                    dr.Item(
"url"= defaultValue
                
End If

                dtXMLFile.Rows.Add(dr)
                
'通过文件流,重新向XML文件中写入新的数据源内容;
                Dim fs As New FileStream(strFilePath, FileMode.Open, FileAccess.Write, FileShare.ReadWrite)
                dtXMLFile.WriteXml(fs)
                fs.Close()

                
'重新绑定GridView
                Me.BoundGridView(dtXMLFile)
                
'Cache.Remove("computerInfo")
                '由于缓存(Cache)以来的XML文件的内容发生了变化,Cache将被清除,
                '这里需要通过调用此函数来重建缓存和缓存依赖项;
                Me.UpdateCache(dtXMLFile)
            
Else
                
Me.MsgBox("dtXMLFile为空(Nothing)")
            
End If
        
Else
            
Me.MsgBox("作为数据源的XML文件不存在!请检查。")
            
Return
        
End If
    
End Sub


    
'用于弹出提示窗口;
    Public Sub MsgBox(ByVal message As String)
        ClientScript.RegisterStartupScript(ClientScript.GetType(), 
"reminderInfo", message)
    
End Sub


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


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


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

            
Me.BoundGridView(dtDataSource)
        
End If
    
End Sub


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

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


 
0
0

查看评论
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
    个人资料
    • 访问:60606次
    • 积分:1291
    • 等级:
    • 排名:千里之外
    • 原创:66篇
    • 转载:7篇
    • 译文:0篇
    • 评论:12条
    优化蜘蛛引导