Partager via


Loading the Cache

Before you can use cached data, you must first load data into the cache. For example, in a retail application, you may want to load data about various products, or all products, into the cache.

Typical Goals

In this scenario, you want to add data to the cache to improve the performance of an application.

Solution

There are two methods you can use for loading data:

  • Proactive loading. This method retrieves all the required state and then caches it for the lifetime of the application or the process.
  • Reactive loading. This method retrieves data when it is requested by the application and then caches it for future requests.

Caching Data Proactively

You can cache data proactively to retrieve all the required state for an application or a process, typically when the application or process starts, and cache it for the lifetime of the application or process.

Advantages of Proactive Loading

Because you can guarantee that the data has been loaded into the cache, in theory you do not have to check whether the state exists in the cache. However, you should check whether an item exists in the cache before retrieving it because the cache may have been flushed.

Your application performance improves because cache operations are optimized when proactively loading state into the cache. Application response times also improve because all the data is cached.

Disadvantages of Proactive Loading

Proactive loading does not result in the most optimized system because much of the state is cached even though it may not all be required. For example, an application may contain 100 processes, and each process may require some items in the cache. If a user launches this application but activates only one process, hundreds of items are needlessly cached.

Proactive caching may result in an implementation more complex than conventional techniques. With conventional techniques, each item is retrieved synchronously in a well-known program flow. Using proactive caching requires working with several threads; therefore, it can be difficult to synchronize the threads with the application's main thread, keep track of thread status, and handle exceptions in an asynchronous programming model.

Recommendations for Proactive Loading

When you implement proactive caching, load as much state as possible when the application initializes or when each process initializes. You should use an asynchronous programming model to load the state on a background thread. If you do not use proactive loading correctly, applications may initialize slowly.

Proactive caching is recommended in situations that have one or more of the following characteristics:

  • You are using static or semi-static state that has known update periods. If you use it in other scenarios, the state might expire before it is used.
  • You are using state with a known lifetime.
  • You are using state of a known size. If you use proactive cache data loading when you do not know the size of the data, you might exhaust system resources. You must try to not use resources that you do not have.
  • You have problematic resources, such as a slow database, a slow network, or unreliable Web services. You can use this technique to retrieve all the state proactively, cache it, and work against the cache as much as possible.

Caching Data Reactively

You reactively cache data by retrieving data as it is requested by the application and caching it for future requests.

Advantages of Reactive Loading

Because you are not loading a lot of data when the application initializes, your system resources are not misused. This method results in an optimized caching system because you are storing only requested items.

Disadvantages of Reactive Loading

Performance might decrease when any piece of data is requested the first time because it must be loaded from the source; it is not retrieved from the cache. Also, you have to check whether an item exists in the cache before you can use it. Checking this in every service agent can cause excessive conditional logic in your code.

Recommendations for Reactive Loading

Reactive caching is recommended in situations with one or more of the following characteristics:

  • You are using a lot of state and you do not have sufficient resources to cache all state for the entire application.
  • You are using reliable and responsive resources, such as a database, network, or Web service, which will not impede application stability or performance.
  • You are interested in caching data that is not available during the initialization of an application. For example, this data might be affected by user input, such as common search queries or user-specific data, such as a user's profile.

For more information about proactive and reactive loading, see Microsoft Application Architecture Guide, 2nd Edition.

Loading Examples

The following code demonstrates one way to proactively load the cache. It reads the data stored in the master data source (in this case, an XML file) and immediately stores it in the cache, using the Add method. The GetProductList method is not a part of the Caching Application Block.

Note

For more information on instantiating objects, see Creating and Referencing Enterprise Library Objects.

public List<Product> GetProductList()
{
  // This returns a list of product objects.
}

public void LoadAllProducts(ICacheManager cache)
{
  List<Product>list = GetProductList();

  for (int i = 0; i < list.Count; i++)
  {
    Product newProduct = list[i];
    cache.Add(newProduct.ProductID, newProduct);
  }
}
'Usage
Public Function GetProductList() As List(Of Product)
  ' This returns a list of product objects.
End Function

Public Sub LoadAllProducts(ByVal cache As ICacheManager)
  Dim list As List(Of Product) = GetProductList()
  Dim i As Integer
  For i = 0 To list.Count - 1
    Dim newProduct As Product = list(i)
    cache.Add(newProduct.ProductID, newProduct)
  Next
End Sub

The following code demonstrates one way to reactively load the cache. It first checks to see whether the item is already in the cache. If it is not, it retrieves it from the master data source (in this case, an XML file) and then adds it to the cache using the Add method. The GetProductByID method is not a part of the Caching Application Block.

public Product GetProductByID(string anID)
{
  // This returns a product object with the specified ID.
} 

public Product ReadProductByID(ICacheManager cache, string productID)
{
  Product newProduct = (Product)cache.GetData(productID);

  // Does our cache already have the requested object?
  if (newProduct == null)
  {
    // The requested object is not cached, so retrieve it from
    // the data provider and cache it for further requests.
    newProduct = this.dataProvider.GetProductByID(productID);

    if (newProduct != null)
    {
      cache.Add(newProductID, newProduct);
    }
  }
  return newProduct;
}
'Usage
Public Function GetProductByID(ByVal anID As String) As Product
  ' This returns a product object with the specified ID.
End Function

Public Function ReadProductByID(ByVal cache As ICacheManager, _
                                ByVal productID As String) As Product

  Dim newProduct As Product = DirectCast(cache.GetData(productID), Product)

  ' Does our cache already have the requested object?
  If (newProduct Is Nothing) Then

    ' The requested object is not cached, so retrieve it from
    ' the data provider and cache it for further requests.
    newProduct = Me.dataProvider.GetProductByID(newProductID)

    If (Not product Is Nothing) Then
      cache.Add(newProductID, newProduct)
    End If
  End If

  Return newProduct

End Function