您的位置:首页精文荟萃软件资讯 → 用.NET创建定时缓存

用.NET创建定时缓存

时间:2004/10/8 13:15:00来源:本站整理作者:蓝点我要评论(0)

在先前的文章里,我详细讨论了.NET缓存的简单用法。不过那点用途还只能是这一话题的“开胃酒”。现在,我们更进一步,在那篇文章所开发的缓存基础上添加条目在缓存中的过期功能。


清单A的内容就是上次我们开发的有关代码。


新缓存及其改进
为了创建定时缓存,我们首先得确定某个对象是否已经到期了。出于这篇文章讨论范围,我假设用户能够确定准确的对象超期日期。这样,在将来还可以再改进为允许在缓存中存放的对象自己确定它们的过期日期。


我们首先修改insertCachedObject方法以支持缓存中对象的过期功能。当对象插入缓存时,该方法会给用户提供一个对象过期日期。这个日期参数被称为dtExpiration。insertCachedObject方法则存储经由该参数传递的过期日期。完成这一目标有若干方法。例如,我们可以创建一个封装对象,其中包含了日期和对象属性。如果这样做的话,insertCachedObject方法就会创建封装对象的实例并提供给它两个属性。我们选择相比更简单些的第二个方案:创建和声明第2个哈希散列表,并且指定它同第一个哈希散列表并行运行。这第二个哈希散列表叫做htExpiration。


对 insertCachedObject 方法的修改请见清单B。


现在,我们需要想办法发现过期的条目。在通过getCachedObject方法发出请求时,简单而且也是最偷懒的办法是检查每个缓冲对象。因为直到发出处理请求才调出过期对象,所以这是一种较差的算法。而且很有可能在时间上具有一定的不确定性。虽然这些到期对象驻留在缓存里,可是它们消费着珍贵的内存资源,这对应用程序的性能具有极其不利的影响。


不用这种偷懒的办法,我们创建一个后台线程反复检查htExpiration哈希表。


于是我们创建一个名叫TheReaperThread的类,这个类有一个方法负责建立无限循环。该类还被声明为内部类,因为它只用在CustomCache对象的上下文环境内。该类的全部代码请见清单C。


你得对清单C中的Shared Constructor注意了,它负责创建新的线程并启动该线程。我们接下来创建测试程序保证缓存运行正常。测试程序见清单D,该程序是一个控制台程序,当然也可以用.NET Framework 把以上程序当作项目来创建。



小结
定时缓存就这样完全实现了。虽然在功能上还比较简单,而且不能通知缓存的用户条目在什么时候到期,也不允许对象确定它们自己的过期算法。不过在这种简单缓存的基础上,将来我们还可以讨论开发新的功能,比如分派、内存管理等等。


Listing A



'Defines a Public Class called CustomCache
Public Class CustomCache
'Declares the hashtable use to store everything put into the cache.
'Since ht is shared there it follows a Singleton pattern
Private Shared ht As System.Collections.Hashtable
'A shared Constructor runs when the class is referenced very first time.
Shared Sub New()
'Instantiates the Hashtable
ht = New Hashtable()
End Sub
'A private constructor prevents clients instantiating CustomCache Object
Private Sub New()
End Sub
'Shared method used to put objects into the cache
Public Shared Sub insertCachedObject(ByVal key As Object, ByVal o As Object)
ht.Add(key, o)
End Sub
'Shared method used to retrieve objects from the cache
Public Shared Function getCachedObject(ByVal key As Object) As Object
Return ht.Item(key)
End Function
End Class



Listing B



Public Shared Sub insertCachedObject(ByVal key As Object, ByVal o As Object, ByVal dtExpiration As Date)
ht.Add(key, o)
'Add the expiration date to the second hashtable using the same key
htExpiration.Add(key, dtExpiration)
End Sub



Listing C



'Imports the Threading namespace - the ThreadStart object resides in it
Imports System.Threading
'Defines a Public Class called CustomCache
Public Class CustomCache
'Declares the hashtable use to store everything put into the cache.
'Since ht is shared there it follows a Singleton pattern
Private Shared ht As System.Collections.Hashtable
Private Shared htExpiration As System.Collections.Hashtable
'This class is responsible for finding expired objects and removing them from the cache
'this class is named TheReaperThread in remembrance of the Grim Reaper!
Class TheReaper
'This method will reap until the cows come home.
Sub ReapBabyReap()
Dim dt As Date
While True
'Output message to the console
Console.WriteLine("The reaper thread is looking for expired objects...")
'Declare an Enumerator - Enumerator are used to iterate collections
Dim myEnumerator As IDictionaryEnumerator
'Instantiate Enumerator
myEnumerator = htExpiration.GetEnumerator()
'Loops through all items
While myEnumerator.MoveNext()
'get the expiration date
dt = myEnumerator.Value
'Output to the console
Console.Write("Key: " + ControlChars.Tab + "{0}, Expires: " + ControlChars.Tab + "{1}", myEnumerator.Key, dt.ToString)
'Compare the date of expiration with the current date and time.
'If its less than or equal to zero in value then item gone
If Date.Compare(dt, Now()) <= 0 Then
'Output to the console
Console.WriteLine(" EXPIRED - Removing")


'Remove the expired item from the main hashtable
ht.Remove(myEnumerator.Key)
'don't forget to remove the expired item htExpiration.Remove(myEnumerator.Key)
' HACK Need to refresh the enumeration.
' This must be done to avoid the exception which occurs otherwise.
' This will cause the loop to restart from the beginning and may
' lead to certain items positioned
' at the end of the hashtable to remain longer than they would otherwise.
' This can be considered a hack and should be revisited
myEnumerator = htExpiration.GetEnumerator()
Else
'output to the console
Console.WriteLine(" Not Expired")
End If
'Give the reaper a break, he doesn't need to check every single second does he?
Thread.Sleep makes the current thread pause execution for specified number of
'milliseconds. This value could be set as a public property of the class.
Thread.Sleep(5000)
End While
End While
End Sub
End Class
'A shared Constructor runs when class referenced the first time.
Shared Sub New()
'Instantiates the Hashtable
ht = New Hashtable()
'Instantiates the Expiration Hashtable
htExpiration = New Hashtable()
'Declare and instantiate the TheReaperThread
Dim grimReaper As New TheReaper()
'Create a ThreadStart object, passing the address of grimReaper.ReapBabyReap.
'ThreadStart is a delegate! We will learn more about these in the next article.
Dim otter As New ThreadStart(AddressOf grimReaper.ReapBabyReap)
'Create a Thread object.
Dim oThread As New Thread(otter)
'Starting the thread invokes the ThreadStart delegate.
oThread.Start()
End Sub
'A private constructor prevents clients from instantiate the CustomCache Object
Private Sub New()
End Sub
'Shared method used to put objects into the cache
'dtExpiration is the date of expiration parameter
Public Shared Sub insertCachedObject(ByVal key As Object, ByVal o As Object, ByVal dtExpiration As Date)
ht.Add(key, o)
'Add the expiration date to the second hashtable using the same key
htExpiration.Add(key, dtExpiration)
End Sub
'Shared method used to retrieve objects from the cache
Public Shared Function getCachedObject(ByVal key As Object) As Object
Return ht.Item(key)
End Function
End Class



Listing D



Module TestCache
Sub Main()
'Creates a String which contains the Alphabet A..Z
Dim s As New String("ABCDEFGHIJKLMNOPQRSTUVWXYZ")
'Inserts the String into the Cache using a string key of "Alphabet"
'Sets the expiration date to the current date and time plus one minute
UnitTest.CustomCache.insertCachedObject("Alphabet", s, Now().AddMinutes(1))
'Declares a Second String called s1
Dim s1 As String
'Retrieves the cache object which matches the key of "Alphabet"
s1 = UnitTest.CustomCache.getCachedObject("Alphabet")
'This should output the alphabet A..X
Console.WriteLine(s1)
'Don't hit the enter key until see item expired in the console window
Console.ReadLine()
'Declares a Third String called s1
Dim s3 As String
'Retrieves the cache object which matches the key of "Alphabet"
s3 = UnitTest.CustomCache.getCachedObject("Alphabet")
'This should output the alphabet A..X
Console.WriteLine(s3)
'By performing a Console.readline it allows us to see the
' output of the console window prior to its closing
Console.ReadLine()
End Sub
End Module


 


相关阅读 Windows错误代码大全 Windows错误代码查询激活windows有什么用Mac QQ和Windows QQ聊天记录怎么合并 Mac QQ和Windows QQ聊天记录Windows 10自动更新怎么关闭 如何关闭Windows 10自动更新windows 10 rs4快速预览版17017下载错误问题Win10秋季创意者更新16291更新了什么 win10 16291更新内容windows10秋季创意者更新时间 windows10秋季创意者更新内容kb3150513补丁更新了什么 Windows 10补丁kb3150513是什么

文章评论
发表评论

热门文章 360快剪辑怎么使用 36金山词霸如何屏幕取词百度收购PPS已敲定!3

最新文章 微信3.6.0测试版更新了微信支付漏洞会造成哪 360快剪辑怎么使用 360快剪辑软件使用方法介酷骑单车是什么 酷骑单车有什么用Apple pay与支付宝有什么区别 Apple pay与贝贝特卖是正品吗 贝贝特卖网可靠吗

人气排行 xp系统停止服务怎么办?xp系统升级win7系统方电脑闹钟怎么设置 win7电脑闹钟怎么设置office2013安装教程图解:手把手教你安装与qq影音闪退怎么办 QQ影音闪退解决方法VeryCD镜像网站逐个数,电驴资料库全集同步推是什么?同步推使用方法介绍QQ2012什么时候出 最新版下载EDiary——一款好用的电子日记本