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 |