ENTERPRISE

Microsoft Enterprise Library : A Cache Advance for Your Applications - How Do I Use the Caching Block (part 1) - Adding Items to and Retrieving Items from the Cache

10/22/2013 8:40:39 PM

You manipulate your caches using the interface of the Cache Manager. It is a relatively simple interface. There are two overloads of the Add method for adding items to the cache; plus methods to retrieve a cached item, remove a single item, flush all items, and check if the cache contains a specified item. The single property, Count, returns the number of items currently in the cache.

1. About the Example Application

Note

Before you attempt to run the example, you must create a new encryption key for the Caching block to use to encrypt the data in one of the examples that uses a symmetric encryption provider. This is because the key is tied to either the user or the machine, and so the key included in the sample files will not work on your machine. In the configuration console, navigate to the Symmetric Cryptography Providers section of the Cryptography Application Block Settings and select the RijndaelManaged provider. Click the " … " button next to the Key property to start the Cryptographic Key Wizard. Use this wizard to generate a new key, save the key file, and automatically update the contents of App.config.

The first of the examples, Cache data in memory using the null backing store, demonstrates some of the options you have when adding items to the cache.

2. Adding Items to and Retrieving Items from the Cache

To add an item to the cache, you can use the simple approach of specifying just the key for the item and the value to cache as parameters to the Add method. The item is cached with a never expired lifetime, and normal priority. If you want more control over the way an item is cached, you can use the other overload of the Add method, which additionally accepts a value for the priority, a reference to a callback that will execute when the cached item expires, and an array of expirations that specify when the item should expire.

Possible values for the priority, as defined in the CacheItemPriority enumeration, are None, Low, Normal, High, and NotRemovable. In addition to the NeverExpired value for the expirations, you can use AbsoluteTime, SlidingTime, FileDependency, and ExtendedFormatTime expirations. If you create an array containing more than one expiration instance, the block will expire the item when any one of these indicates that it has expired.

The example starts by obtaining a reference to an instance of a CacheManager—in this case one that has no backing store defined in its configuration (or, to be more precise, it has the NullBackingStore class defined) and so uses only the in-memory cache. It stores this reference as the interface type ICacheManager.

Next, it calls a separate routine that adds items to the cache and then displays the contents of the cache.

// Resolve the default CacheManager object from the container.
// The actual concrete type is determined by the configuration settings.
// In this example, the default is the InMemoryCacheManager instance.
ICacheManager defaultCache
= EnterpriseLibraryContainer.Current.GetInstance<ICacheManager>();
// Store some items in the cache and show the contents using a separate routine.
CacheItemsAndShowCacheContents(defaultCache);

The CacheItemsAndShowCacheContents routine uses the cache manager passed to it; in this first example, this is the in-memory only cache manager. However, the code to add items to the cache and manipulate the cache is (as you would expect) identical for all configurations of cache managers. Notice that the code defines a set of string values that it uses as the cache keys. This makes it easier for the code later on to examine the contents of the cache. This is the declaration of the cache keys array and the first part of the code in the CacheItemsAndShowCacheContents routine.

// Declare an array of string values to use as the keys of the cached items.
string[] DemoCacheKeys
= {"ItemOne", "ItemTwo", "ItemThree", "ItemFour", "ItemFive"};
void CacheItemsAndShowCacheContents(ICacheManager theCache)
{
// Add some items to the cache using the key names in the DemoCacheKeys array.
theCache.Add(DemoCacheKeys[0], "Some Text");
theCache.Add(DemoCacheKeys[1],
new StringBuilder("Some text in a StringBuilder"));
theCache.Add(DemoCacheKeys[2], 42, CacheItemPriority.High, null,
new NeverExpired());
theCache.Add(DemoCacheKeys[3], new DataSet(), CacheItemPriority.Normal,
null, new AbsoluteTime(new DateTime(2099, 12, 31)));
// Note that the next item will expire after three seconds
theCache.Add(DemoCacheKeys[4],
new Product(10, "Exciting Thing", "Useful for everything"),
CacheItemPriority.Low, null,
new SlidingTime(new TimeSpan(0, 0, 3)));
// Display the contents of the cache.
ShowCacheContents(theCache);
...

In the code shown above, you can see that the CacheItemsAndShowCacheContents routine uses the simplest overload to cache the first two items; a String value and an instance of the StringBuilder class. For the third item, the code specifies the item to cache as the Integer value 42 and indicates that it should have high priority (it will remain in the cache after lower priority items when the cache has to be minimized due to memory or other constraints). There is no callback required, and the item will never expire.

The fourth item cached by the code is a new instance of the DataSet class, with normal priority and no callback. However, the expiry of the cached item is set to an absolute date and time (which should be well after the time that you run the example).

The final item added to the cache is a new instance of a custom class defined within the application. The Product class is a simple class with just three properties: ID, Name, and Description. The class has a constructor that accepts these three values and sets the properties in the usual way. It is cached with low priority, and a sliding time expiration set to three seconds.

The final line of code above calls another routine named ShowCacheContents that displays the contents of the cache. Not shown here is code that forces execution of the main application to halt for five seconds, redisplay the contents of the cache, and repeat this process again. This is the output you see when you run this example.

The cache contains the following 5 item(s):
Item key 'ItemOne' (System.String) = Some Text
Item key 'ItemTwo' (System.Text.StringBuilder) = Some text in a StringBuilder
Item key 'ItemThree' (System.Int32) = 42
Item key 'ItemFour' (System.Data.DataSet) = System.Data.DataSet
Item key 'ItemFive' (CachingExample.Product) = CachingExample.Product
Waiting for last item to expire...
Waiting... Waiting... Waiting... Waiting... Waiting...
The cache contains the following 5 item(s):
Item key 'ItemOne' (System.String) = Some Text
Item key 'ItemTwo' (System.Text.StringBuilder) = Some text in a StringBuilder
Item key 'ItemThree' (System.Int32) = 42
Item key 'ItemFour' (System.Data.DataSet) = System.Data.DataSet
Item with key 'ItemFive' has been invalidated.
Waiting for the cache to be scavenged...
Waiting... Waiting... Waiting... Waiting... Waiting...
The cache contains the following 4 item(s):
Item key 'ItemOne' (System.String) = Some Text
Item key 'ItemTwo' (System.Text.StringBuilder) = Some text in a StringBuilder
Item key 'ItemThree' (System.Int32) = 42
Item key 'ItemFour' (System.Data.DataSet) = System.Data.DataSet

You can see in this output that the cache initially contains the five items we added to it. However, after a few seconds, the last one expires. When the code examines the contents of the cache again, the last item (with key ItemFive) has expired but is still in the cache. However, the code detects this and shows it as invalidated. After a further five seconds, the code checks the contents of the cache again, and you can see that the invalidated item has been removed.

Note

Depending on the performance of your machine, you may need to change the value configured for the expiration poll frequency of the cache manager in order to see the invalidated item in the cache and the contents after the scavenging cycle completes.

What's In My Cache?

The example you've just seen displays the contents of the cache, indicating which items are still available in the cache, and which (if any) are in the cache but not available because they are waiting to be scavenged. So how can you tell what is actually in the cache and available for use? In the time-honored way, you might like to answer "Yes" or "No" to the following questions:

  • Can I use the Contains method to check if an item with the key I specify is available in the cache?

  • Can I query the Count property and retrieve each item using its index?

  • Can I iterate over the collection of cached items, reading each one in turn?

If you answered "Yes" to any of these, the bad news is that you are wrong. All of these are false. Why? Because the cache is managed by more than one process. The cache manager you are using is responsible for adding items to the cache and retrieving them through the public methods available to your code. However, a background process also manages the cache, checking for any items that have expired and removing (scavenging) those that are no longer valid. Cached items may be removed when memory is scarce, or in response to dependencies on other items, as well as when the expiry date and time you specified when you added an item to the cache has passed.

So, even if the Contains method returns true for a specified cache key, that item might have been invalidated and is only in the cache until the next scavenging operation. You can see this in the output for the previous example, where the two waits force the code to halt until the item has been flagged as expired, and then halt again until it is scavenged. The actual delay before scavenging takes place is determined by the expiration poll frequency configuration setting of the cache manager. In the previous example, this is 10 seconds.

The correct approach to extracting cached items is to simply call the GetData method and check that it did not return null. However, you can use the Contains method to see if an item was previously cached and will (in most cases) still be available in the cache. This is efficient, but you must still (and always) check that the returned item is not null after you attempt to retrieve it from the cache.

The code used in the examples to read the cached items depends on the fact that we use an array of cache keys throughout the examples, and we can therefore check if any of these items are in the cache. The code we use is shown here.

void ShowCacheContents(ICacheManager theCache)
{
if (theCache.Count > 0)
{
Console.WriteLine("Cache contains the following {0} item(s):",
theCache.Count);
// Cannot iterate the cache, so use the five known keys
foreach (string key in DemoCacheKeys)
{
if (theCache.Contains(key))
{
// Try and get the item from the cache
object theData = theCache.GetData(key);
// If item has expired but not yet been scavenged, it will still show
// in the count of the number of cached items, but the GetData method
// will return null.
if (null != theData)
Console.WriteLine("Item key '{0}' ({1}) = {2}", key,
theData.GetType().ToString(), theData.ToString());
else
Console.WriteLine("Item with key '{0}' has been invalidated.", key);
}
}
}
else
{
Console.WriteLine("The cache is empty.");
}
}
Other  
  •  Microsoft Enterprise Library : A Cache Advance for Your Applications - How Do I Configure the Caching Block?
  •  Microsoft Visual Studio 2010 : Data Parallelism - Unrolling Sequential Loops into Parallel Tasks (part 4) - Handling Exceptions
  •  Microsoft Visual Studio 2010 : Data Parallelism - Unrolling Sequential Loops into Parallel Tasks (part 3) - Interrupting a Loop
  •  Microsoft Visual Studio 2010 : Data Parallelism - Unrolling Sequential Loops into Parallel Tasks (part 2) - The Parallel For Loop
  •  Microsoft Visual Studio 2010 : Data Parallelism - Unrolling Sequential Loops into Parallel Tasks (part 1)
  •  Programming Windows Services with Microsoft Visual Basic 2008 : Implementing the Worker Class, Creating the FileWorkerOptions Class
  •  Programming Windows Services with Microsoft Visual Basic 2008 : Extending the Threading Model
  •  Programming Windows Services with Microsoft Visual Basic 2008 : Writing a New Thread Method, Monitoring with Multiple Threads
  •  The HP Virtual Server Environment : Example nPartition Management Scenario (part 4) - Rebooting and Booting nPartitions
  •  The HP Virtual Server Environment : Example nPartition Management Scenario (part 3) - Creating a new nPartition
  •  
    Video
    Video tutorials
    - How To Install Windows 8

    - How To Install Windows Server 2012

    - How To Install Windows Server 2012 On VirtualBox

    - How To Disable Windows 8 Metro UI

    - How To Install Windows Store Apps From Windows 8 Classic Desktop

    - How To Disable Windows Update in Windows 8

    - How To Disable Windows 8 Metro UI

    - How To Add Widgets To Windows 8 Lock Screen

    - How to create your first Swimlane Diagram or Cross-Functional Flowchart Diagram by using Microsoft Visio 2010
    programming4us programming4us
    Top 10
    Free Mobile And Desktop Apps For Accessing Restricted Websites
    MASERATI QUATTROPORTE; DIESEL : Lure of Italian limos
    TOYOTA CAMRY 2; 2.5 : Camry now more comely
    KIA SORENTO 2.2CRDi : Fuel-sipping slugger
    How To Setup, Password Protect & Encrypt Wireless Internet Connection
    Emulate And Run iPad Apps On Windows, Mac OS X & Linux With iPadian
    Backup & Restore Game Progress From Any Game With SaveGameProgress
    Generate A Facebook Timeline Cover Using A Free App
    New App for Women ‘Remix’ Offers Fashion Advice & Style Tips
    SG50 Ferrari F12berlinetta : Prancing Horse for Lion City's 50th
    Popular Tags
    Video Tutorail Microsoft Access Microsoft Excel Microsoft OneNote Microsoft PowerPoint Microsoft Project Microsoft Visio Microsoft Word Active Directory Exchange Server Sharepoint Sql Server Windows Server 2008 Windows Server 2012 Windows 7 Windows 8 Adobe Flash Professional Dreamweaver Adobe Illustrator Adobe Photoshop CorelDRAW X5 CorelDraw 10 windows Phone 7 windows Phone 8 Iphone