6. Removing Items from and Flushing the Cache
Having seen how you can add items to your cache, and use a
variety of backing store options and encryption, it's time now to see
how you can manipulate the cache to remove items, or clear it
completely by flushing it. Items are removed from the cache
automatically based on their expiration or dependencies, but you can
also remove individual items or remove all items.
The example, Remove and flush cached items,
actually demonstrates more than just removing and flushing items—it
shows how you can use a dependency to remove related items from your
cache, how to create extended time expirations, and how to use an array of expirations. There is quite a lot
of code in this example, so we'll step through it and explain each
part in turn.
Using a File Dependency and Extended Time Expiration
The example starts by creating a NeverExpired expiration instance, followed by
writing a text file to the current execution folder. It then creates
a FileDependencyHowever, if the original file is changed or deleted,
you want the equivalent cached item to be removed from the cache. on that file. This
is a typical scenario where you read data from a file, such as a
text file or an XML document, which you will access frequently in
your code.
// Create an expiration that never expires
NeverExpired never = new NeverExpired();
// Create a text file to use in a FileDependency
File.AppendAllText("ATextFile.txt", "Some contents for the file");
// Create an expiration dependency on the new text file
FileDependency fileDep = new FileDependency("ATextFile.txt");
Next, the code creates an instance of the ExtendedFormatTime
class. This class allows you to specify expiration
times for the cached item based on a repeating schedule. It provides
additional opportunities compared to the more common SlidingTime and AbsoluteTime expiration types you have seen
so far.
The constructor of the ExtendedFormatTime class accepts a string
value that it parses into individual values for the minute, hour,
day, month, and weekday (where zero is Sunday) that together specify
the frequency with which the cached item will expire. Each value is
delimited by a space. An asterisk indicates that there is no value
for that part of the format string, and effectively means that
expiration will occur for every occurrence of that item. It all
sounds very complicated, so some examples will no doubt be useful
(see Table 1).
Table 1. Expiration
Extended Format String |
Meaning |
---|
* * * *
* |
Expires every minute. |
5 * * *
* |
Expires at the 5th minute of every
hour. |
* 21 * *
* |
Expires every minute of the 21st hour of every
day. |
31 15 * *
* |
Expires at 3:31 PM every day. |
7 4 * *
6 |
Expires every Saturday 4:07 AM. |
15 21 4 7
* |
Expires at 9:15 PM on every
4th of July. |
The example generates an ExtendedFormatTime that expires at 30 minutes
past every hour. Then it creates an array of type ICacheItemExpiration that contains the
File Dependency created earlier and
the new ExtendedFormatTime
instance.
// Create an extended expiration for 30 minutes past every hour
ExtendedFormatTime extTime = new ExtendedFormatTime("30 * * * *");
// Create array of expirations containing the file dependency and extended format
ICacheItemExpiration[] expirations
= new ICacheItemExpiration[] { fileDep, extTime };
Adding the Items to the Cache
Now (at last) the code can add some items to the cache. It
adds four items: the first uses the NeverExpired expiration, the second uses the
array that contains the file dependency and extended format time
expiration, and the other two just use the simple approach to
caching items . The code then displays the contents of the cache and
waits for you to press a key.
// Add items to the cache using the key string names in the DemoCacheKeys array.
defaultCache.Add(DemoCacheKeys[0], "A cached item that never expires",
CacheItemPriority.NotRemovable, null, never);
defaultCache.Add(DemoCacheKeys[1], "A cached item that depends on both "
+ "a disk file and an hourly extended time expiration.",
CacheItemPriority.Normal, null, expirations);
defaultCache.Add(DemoCacheKeys[2], "Another cached item");
defaultCache.Add(DemoCacheKeys[3], "And yet another cached item.");
ShowCacheContents(defaultCache);
Console.Write("Press any key to delete the text file...");
Console.ReadKey(true);
The following is the output you see at this point in the
execution.
Created a 'never expired' dependency.
Created a text file named ATextFile.txt to use as a dependency.
Created an expiration for 30 minutes past every hour.
Cache contains the following 4 item(s):
Item key 'ItemOne' (System.String) = A cached item that never expires
Item key 'ItemTwo' (System.String) = A cached item that depends on both a disk
file and an hourly extended time expiration.
Item key 'ItemThree' (System.String) = Another cached item
Item key 'ItemFour' (System.String) = And yet another cached item.
When you press a key, the code continues by deleting the text
file, and then re-displaying the contents of the cache. Then, as in
earlier examples, it waits for the items to be scavenged from the
cache. The output you see is shown here.
Cache contains the following 4 item(s):
Item key 'ItemOne' (System.String) = A cached item that never expires
Item with key 'ItemTwo' has been invalidated.
Item key 'ItemThree' (System.String) = Another cached item
Item key 'ItemFour' (System.String) = And yet another cached item.
Waiting for the dependent item to be scavenged from the cache...
Waiting... Waiting... Waiting... Waiting...
Cache contains the following 3 item(s):
Item key 'ItemOne' (System.String) = A cached item that never expires
Item key 'ItemThree' (System.String) = Another cached item
Item key 'ItemFour' (System.String) = And yet another cached item.
You can see that deleting the text file caused the item with
key ItemTwo that depended on it to be
invalidated and removed during the next scavenging cycle.
At this point, the code is again waiting for you to press a
key. When you do, it continues by calling the Remove method of the cache manager to remove
the item having the key ItemOne, and displays the cache contents
again. Then, after you press a key for the third time, it calls the
Flush method of the cache manager to
remove all the items from the cache, and again calls the method that
displays the contents of the cache. This is the code for this part
of the example.
Console.Write("Press any key to remove {0} from the cache...", DemoCacheKeys[0]);
Console.ReadKey(true);
defaultCache.Remove(DemoCacheKeys[0]);
ShowCacheContents(defaultCache);
Console.Write("Press any key to flush the cache...");
Console.ReadKey(true);
defaultCache.Flush();
ShowCacheContents(defaultCache);
The result you see as this code executes is shown here.
Press any key to remove ItemOne from the cache...
Cache contains the following 2 item(s):
Item key 'ItemThree' (System.String) = Another cached item
Item key 'ItemFour' (System.String) = And yet another cached item.
Press any key to flush the cache...
The cache is empty.