programming4us
programming4us
ENTERPRISE

Microsoft Enterprise Library : A Cache Advance for Your Applications - How Do I Use the Caching Block (part 4) - Refreshing the Cache, Loading the Cache

- How To Install Windows Server 2012 On VirtualBox
- How To Bypass Torrent Connection Blocking By Your ISP
- How To Install Actual Facebook App On Kindle Fire
10/22/2013 8:46:45 PM

7. Refreshing the Cache

So far, when we used the Add method to add items to the cache, we passed a null value for the refreshAction parameter. You can use this parameter to detect when an item is removed from the cache, and discover the value of that item and the reason it was removed.

You must create a class that implements the ICacheItemRefreshAction interface, and contains a method named Refresh that accepts as parameters the key of the item being removed, the value as an Object type, and a value from the CacheItemRemovedReason enumeration. The values from this enumeration are Expired, Removed (typically by your code or a dependency), Scavenged (typically in response to shortage of available memory), and Unknown (a reserved value you should avoid using).

Therefore, inside your Refresh method, you can query the parameter values passed to it to obtain the key and the final cached value of the item, and see why it was removed from the cache. At this point, you can make a decision on what to do about it. In some cases, it may make sense to insert the item into the cache again (such as when a file on which the item depends has changed, or if the data is vital to your application). Of course, you should generally only do this if it expired or was removed. If items are being scavenged because your machine is short of memory, you should think carefully about what you want to put back into the cache!

The example, Detect and refresh expired or removed cache items, illustrates how you can capture items being removed from the cache, and re-cache them when appropriate. The example uses the following implementation of the ICacheItemRefreshAction interface to handle the case when the cache contains instances of the Product type. For a general situation where you cache different types, you would probably want to check the type before attempting to cast it to the required target type. Also notice that the class carries the Serializable attribute. All classes that implement the ICacheItemRefreshAction interface must be marked as serializable.

[Serializable]
public class MyCacheRefreshAction : ICacheItemRefreshAction
{
public void Refresh(string key, object expiredValue,
CacheItemRemovedReason removalReason)
{
// Item has been removed from cache. Perform desired actions here, based on
// the removal reason (for example, refresh the cache with the item).
Product expiredItem = (Product)expiredValue;
Console.WriteLine("Cached item {0} was expired in the cache with "
+ "the reason '{1}'", key, removalReason);
Console.WriteLine("Item values were: ID = {0}, Name = '{1}', "
+ "Description = {2}", expiredItem.ID,
expiredItem.Name, expiredItem.Description);
// Refresh the cache if it expired, but not if it was explicitly removed
if (removalReason == CacheItemRemovedReason.Expired)
{
CacheManager defaultCache = EnterpriseLibraryContainer.Current.GetInstance
<CacheManager>("InMemoryCacheManager");
defaultCache.Add(key, new Product(10, "Exciting Thing",
"Useful for everything"), CacheItemPriority.Low,
new MyCacheRefreshAction(),
new SlidingTime(new TimeSpan(0, 0, 10)));
Console.WriteLine("Refreshed the item by adding it to the cache again.");
}
}
}

To use the implementation of the ICacheItemRefreshAction interface, you simply specify it as the refreshAction parameter of the Add method when you add an item to the cache. The example uses the following code to cache an instance of the Product class that will expire after three seconds.

defaultCache.Add(DemoCacheKeys[0], new Product(10, "Exciting Thing",
"Useful for everything"),
CacheItemPriority.Low, new MyCacheRefreshAction(),
new SlidingTime(new TimeSpan(0, 0, 3)));

The code then does the same as the earlier examples: it displays the contents of the cache, waits five seconds for the item to expire, displays the contents again, waits five more seconds until the item is scavenged, and then displays the contents for the third time. However, this time the Caching block executes the Refresh method of our ICacheItemRefreshAction callback as soon as the item is removed from the cache. This callback displays a message indicating that the cached item was removed because it had expired, and that it has been added back into the cache. You can see it in the final listing of the cache contents shown here.

The cache contains the following 1 item(s):
Item key 'ItemOne' (CachingExample.Product) = CachingExample.Product
Waiting... Waiting... Waiting... Waiting... Waiting...
The cache contains the following 1 item(s):
Item with key 'ItemOne' has been invalidated.
Cached item ItemOne was expired in the cache with the reason 'Expired'
Item values were: ID = 10, Name = 'Exciting Thing', Description = Useful for
everything
Refreshed the item by adding it to the cache again.
Waiting... Waiting... Waiting...
The cache contains the following 1 item(s):
Item key 'ItemOne' (CachingExample.Product) = CachingExample.Product

8. Loading the Cache

If you have configured a persistent backing store for a cache manager, the Caching block will automatically load the in-memory cache from the backing store when you instantiate that cache manager. Usually, this will occur when the application starts up. This is an example of proactive cache loading. Proactive cache loading is useful if you know that the data will be required, and it is unlikely to change much. Another approach is to create a class with a method that reads data you require from some data source, such as a database or an XML file, and loads this into the cache by calling the Add method for each item. If you execute this on a background or worker thread, you can load the cache without affecting the interactivity of the application or blocking the user interface.

Alternatively, you may prefer to use reactive cache loading. This approach is useful for data that may or may not be used, or data that is relatively volatile. In this case (if you are using a persistent backing store), you may choose to instantiate the cache manager only when you need to load the data. Alternatively, you can flush the cache (probably when your application ends) and then load specific items into it as required and when required. For example, you might find that you need to retrieve the details of a specific product from your corporate data store for display in your application. At this point, you could choose to cache it if it may be used again within a reasonable period and is unlikely to change during that period.

Proactive Cache Loading

The example, Load the cache proactively on application startup, provides a simple demonstration of proactive cache loading. In the startup code of your application you add code to load the cache with the items your application will require. The example creates a list of Product items, and then iterates through the list calling the Add method of the cache manager for each one. You would, of course, fetch the items to cache from the location (such as a database) appropriate for your own application. It may be that the items are available as a list, or—for example—by iterating through the rows in a DataSet or a DataReader.

// Create a list of products - may come from a database or other repository
List<Product> products = new List<Product>();
products.Add(new Product(42, "Exciting Thing",
"Something that will change your view of life."));
products.Add(new Product(79, "Useful Thing",
"Something that is useful for everything."));
products.Add(new Product(412, "Fun Thing",
"Something that will keep the grandchildren quiet."));
// Iterate the list loading each one into the cache
for (int i = 0; i < products.Count; i++)
{
theCache.Add(DemoCacheKeys[i], products[i]);
}

Reactive Cache Loading

Reactive cache loading simply means that you check if an item is in the cache when you actually need it, and—if not—fetch it and then cache it for future use. You may decide at this point to fetch several items if the one you want is not in the cache. For example, you may decide to load the complete product list the first time that a price lookup determines that the products are not in the cache.

The example, Load the cache reactively on demand, demonstrates the general pattern for reactive cache loading. After displaying the contents of the cache (to show that it is, in fact, empty) the code attempts to retrieve a cached instance of the Product class. Notice that this is a two-step process in that you must check that the returned value is not null.

If the item is in the cache, the code displays the values of its properties. If it is not in the cache, the code executes a routine to load the cache with all of the products. This routine is the same as you saw in the previous example of loading the cache proactively.

Console.WriteLine("Getting an item from the cache...");
Product theItem = (Product)defaultCache.GetData(DemoCacheKeys[1]);
// You could test for the item in the cache using CacheManager.Contains(key)
// method, but you still must check if the retrieved item is null even
// if the Contains method indicates that the item is in the cache:
if (null != theItem)
{
Console.WriteLine("Cached item values are: ID = {0}, Name = '{1}', "
+ "Description = {2}", theItem.ID, theItem.Name,
theItem.Description);
}
else
{
Console.WriteLine("The item could not be obtained from the cache.");
// Item not found, so reactively load the cache
LoadCacheWithProductList(defaultCache);
Console.WriteLine("Loaded the cache with the list of products.");
ShowCacheContents(defaultCache);
}

After displaying the contents of the cache after loading the list of products, the example code then continues by attempting once again to retrieve the value and display its properties. You can see the entire output from this example here.

The cache is empty.
Getting an item from the cache...
The item could not be obtained from the cache.
Loaded the cache with the list of products.
The cache contains the following 3 item(s):
Item key 'ItemOne' (CachingExample.Product) = CachingExample.Product
Item key 'ItemTwo' (CachingExample.Product) = CachingExample.Product
Item key 'ItemThree' (CachingExample.Product) = CachingExample.Product
Getting an item from the cache...
Cached item values are: ID = 79, Name = 'Useful Thing', Description = Something
that is useful for everything.

In general, the pattern for a function that performs reactive cache loading is:

  1. Check if the item is in the cache and the value returned is not null.

  2. If it is found in the cache, return it to the calling code.

  3. If it is not found in the cache, create or obtain the object or value and cache it.

  4. Return this new value or object to the calling code.

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
  •  
    Top 10
    - Microsoft Visio 2013 : Adding Structure to Your Diagrams - Finding containers and lists in Visio (part 2) - Wireframes,Legends
    - Microsoft Visio 2013 : Adding Structure to Your Diagrams - Finding containers and lists in Visio (part 1) - Swimlanes
    - Microsoft Visio 2013 : Adding Structure to Your Diagrams - Formatting and sizing lists
    - Microsoft Visio 2013 : Adding Structure to Your Diagrams - Adding shapes to lists
    - Microsoft Visio 2013 : Adding Structure to Your Diagrams - Sizing containers
    - Microsoft Access 2010 : Control Properties and Why to Use Them (part 3) - The Other Properties of a Control
    - Microsoft Access 2010 : Control Properties and Why to Use Them (part 2) - The Data Properties of a Control
    - Microsoft Access 2010 : Control Properties and Why to Use Them (part 1) - The Format Properties of a Control
    - Microsoft Access 2010 : Form Properties and Why Should You Use Them - Working with the Properties Window
    - Microsoft Visio 2013 : Using the Organization Chart Wizard with new data
    REVIEW
    - First look: Apple Watch

    - 3 Tips for Maintaining Your Cell Phone Battery (part 1)

    - 3 Tips for Maintaining Your Cell Phone Battery (part 2)
    programming4us programming4us
    programming4us
     
     
    programming4us