Design of the Expiration Process
The Caching Application Block's expiration process is performed by the BackgroundScheduler. It periodically examines the cached items in the hash table to see if any items have expired. You control how frequently the expiration cycle occurs when you configure an instance of the ICacheManager interface default implementation CacheManager by using the configuration tools.
The expiration policies provided with the Caching Application Block are these:
- Absolute. This means the item expires at a specific time.
- Sliding. This means the item expires after the specified time has elapsed from when the item was last accessed. The default time is 2 minutes.
- Extended format. This allows you to specify very detailed expiration conditions. For example, you can specify that an item expires every Saturday night at 10:03 PM or on the third Tuesday of each month. Extended formats are listed in the ExtendedFormat.cs file.
- File dependency. This means the item expires when a specific file is modified.
- Never expired. This means the item will never expire, although it may still be removed if the block detects a lack of available memory.
The first three policies, absolute, sliding, and extended format, are referred to as time-based expirations. You should use time-based expiration for volatile cache items, such as those that have regular data refreshes or those that are valid for only a specified time. Time-based expiration lets you set policies that keep items in the cache only as long as their data remains current. For example, if you are writing an application that tracks currency exchange rates by obtaining the data from a frequently updated Web site, you can cache the currency rates for the time that those rates remain constant on the source Web site. In this situation, you would set an expiration policy that is based on the frequency of the Web site updates.
The fourth policy, file dependency, is referred to as a notification-based expiration. It defines the validity of a cached item based on a particular file. If the file is modified, the cached item is invalidated and removed from the cache.
The Add method has two overloads. One overload assumes the default expiration policy, which is NeverExpired. The other overload lets you set the expiration policies yourself. You can use as many policies as you want, including policies that you create yourself. (For more information about extending the Caching Application Block by adding your own expiration policies, see Extending and Modifying the Caching Application Block.) If you have an item with multiple policies, the item will expire if any one of the policy's criteria is met.
Marking and Sweeping
Expiration is a two-part process. The first part is referred to as marking; the second part is referred to as sweeping. The process is divided into separate tasks to avoid any conflicts that can occur if the application is using a cache item that BackgroundScheduler is trying to expire.
During marking, BackgroundScheduler makes a copy of the hash table and examines each cache item in it to see if it can be expired. It locks the item while it is doing this. If an item is eligible for expiration, BackgroundScheduler sets a flag in the cache item.
During sweeping, BackgroundScheduler re-examines each flagged CacheItem to see if it has been accessed since it was flagged. If it has been accessed, the item is kept in the cache. If it has not been accessed, it is expired and removed from the cache.
Callbacks
Optionally, developers can use an overload of the Add method that lets them specify that the application will receive a callback after an item expires and is removed from the cache. If necessary, the application can refresh the item.
Items may still be in the cache when an application quits and it is likely that many of those items will have expired when the application restarts. In this case, the items remain in the cache and callbacks for those items occur during the first expiration cycle. However, if an application requests an expired item before the first expiration cycle occurs, the cache performs a callback and returns null to the application. This ensures that a callback occurs for every expired item while preventing an application from receiving an item that has expired.