自定义缓存应用程序块中的一个缓存过期依赖项

一、在添加一个缓存项时,允许指定一个过期策略,这个过期策略对象要实现ICacheItemExpiration接口,常见的过期策略有:

 

绝对过期时间 AbsoluteTime

表达式表示的时间过期策略:ExtendedFormatTime

程序运行中一直不会过期NeverExpired

每次读取之后,再延长指定的时间后才会过期:SlidingTime

文件依赖:FileDependency

 

二、自己实现一个,缓存项依赖:CacheItemDependency

 

参考FileDependency的实现,缓存项的过期与否取决于文件是否发生了变化,我们自己实现一个过期策略,就是缓存项的过期与否取决于另一个NeverExpired的缓存项是否发生了变化。

代码如下:

 

ContractedBlock.gif ExpandedBlockStart.gif Code
[Serializable]
    [ComVisible(
false)]
    
public class CacheItemDependency : ICacheItemExpiration
ExpandedBlockStart.gifContractedBlock.gif    
{
        
private readonly string dependencyCacheKey;

        
private System.Int32 lastCount;

ContractedSubBlock.gifExpandedSubBlockStart.gif        
Constructor#region Constructor
ExpandedSubBlockStart.gifContractedSubBlock.gif        
/**//// <summary>
        
///    Constructor with one argument.
        
/// </summary>
        
/// <param name="cacheKey">Indicates the key of the cache item</param>

        public CacheItemDependency(string cacheKey)
ExpandedSubBlockStart.gifContractedSubBlock.gif        
{
            dependencyCacheKey 
= cacheKey;
            ICacheManager cacheManager 
= CacheFactory.GetCacheManager();
            lastCount 
= Int32.MinValue;
            
if (cacheManager != null)
ExpandedSubBlockStart.gifContractedSubBlock.gif            
{
                
if (cacheManager.Contains(cacheKey))
ExpandedSubBlockStart.gifContractedSubBlock.gif                
{
                    
object o = cacheManager.GetData(cacheKey);
                    
if (o != null)
ExpandedSubBlockStart.gifContractedSubBlock.gif                    
{
                        
this.lastCount = (int)o;
                    }


                    lastCount 
= (int)cacheManager.GetData(cacheKey);
                }

                
else
ExpandedSubBlockStart.gifContractedSubBlock.gif                
{
                    cacheManager.Add(cacheKey, lastCount);
                }

            }

        }

        
#endregion


ContractedSubBlock.gifExpandedSubBlockStart.gif        
Properties#region Properties
ExpandedSubBlockStart.gifContractedSubBlock.gif        
/**//// <summary>
        
/// Gets the key of the dependent Cache Item.
        
/// </summary>
        
/// <value>
        
/// The key of the dependent Cache Item.
        
/// </value>

        public string DependencyCacheKey
ExpandedSubBlockStart.gifContractedSubBlock.gif        
{
ExpandedSubBlockStart.gifContractedSubBlock.gif            
get return dependencyCacheKey; }
        }

ExpandedSubBlockStart.gifContractedSubBlock.gif        
/**//// <summary>
        
/// Gets the Last Count.
        
/// </summary>
        
/// <value>
        
/// The Count of the last setup.
        
/// </value>

        public System.Int32 LastCount
ExpandedSubBlockStart.gifContractedSubBlock.gif        
{
ExpandedSubBlockStart.gifContractedSubBlock.gif            
get return lastCount; }
        }

        
#endregion


ContractedSubBlock.gifExpandedSubBlockStart.gif        
ICacheItemExpiration Members#region ICacheItemExpiration Members
ExpandedSubBlockStart.gifContractedSubBlock.gif        
/**//// <summary>
        
///    Specifies if the item has expired or not.
        
/// </summary>
        
/// <returns>Returns true if the item has expired, otherwise false.</returns>

        public bool HasExpired()
ExpandedSubBlockStart.gifContractedSubBlock.gif        
{
            ICacheManager cacheManager 
= CacheFactory.GetCacheManager();
            
//throw new Exception("The method or operation is not implemented.");
            if (cacheManager == null)
ExpandedSubBlockStart.gifContractedSubBlock.gif            
{
                
return true;
            }


            System.Int32 currentCount 
= (int)cacheManager.GetData(dependencyCacheKey);
            
if (currentCount != lastCount)
ExpandedSubBlockStart.gifContractedSubBlock.gif            
{
                
return true;
            }

            
else
ExpandedSubBlockStart.gifContractedSubBlock.gif            
{
                
return false;
            }

        }


ExpandedSubBlockStart.gifContractedSubBlock.gif        
/**//// <summary>
        
///    Notifies that the item was recently used.
        
/// </summary>

        public void Notify()
ExpandedSubBlockStart.gifContractedSubBlock.gif        
{
        }


ExpandedSubBlockStart.gifContractedSubBlock.gif        
/**//// <summary>
        
/// Not used
        
/// </summary>
        
/// <param name="owningCacheItem">Not used</param>

        public void Initialize(CacheItem owningCacheItem)
ExpandedSubBlockStart.gifContractedSubBlock.gif        
{
        }

        
#endregion

    }

 

三、使用方法

1、更新缓存所依赖的缓存项。代码如下:

 

ContractedBlock.gif ExpandedBlockStart.gif Code
ExpandedBlockStart.gifContractedBlock.gif/**//// <summary>
/// 更新所有以cacheKeys中元素为key的缓存项
        
/// </summary>
        
/// <param name="cacheKeys">缓存项的key的数组</param>

        public static void UpdateCacheDependency(string[] cacheKeys)
ExpandedBlockStart.gifContractedBlock.gif        
{
            ICacheManager cacheManager 
= CacheFactory.GetCacheManager();
            
foreach (string cacheKey in cacheKeys)
ExpandedSubBlockStart.gifContractedSubBlock.gif            
{
                
string cacheItemCache = GetCacheKey(cacheKey);
                
if (cacheManager != null && cacheManager.Contains(cacheItemCache))
ExpandedSubBlockStart.gifContractedSubBlock.gif                
{
                    
int lastCount = (int)cacheManager.GetData(cacheItemCache);
                    
if (lastCount < Int32.MaxValue)
ExpandedSubBlockStart.gifContractedSubBlock.gif                    
{
                        lastCount
++;
                    }

                    
else
ExpandedSubBlockStart.gifContractedSubBlock.gif                    
{
                        lastCount 
= Int32.MinValue;
                    }

                    
// 这一句的作用在于更新以cacheKey为key的缓存项,从而使依赖于此缓存项的缓存项失效.
                    
// 当以cacheKey为Key的缓存项中的数据(这里是lastCount)变化时,是的依赖于此缓存项的缓存失效
                    cacheManager.Add(cacheKey, lastCount);
                }

            }

        }

 

2、每次更新数据库中的表时,调用UpdateCacheDependency方法。

在上述代码中cacheKey可以用数据库中标的名称。

还有一个问题就是 每次更新数据库中的表时,都要调用UpdateCacheDependency方法,是不是很烦,这也是没有办法的,必须调用,否则 依赖于 以cacheKey为Key的缓存项 的缓存项 不会失效,一般可以在数据访问的基类中将Insert\Update\Delete执行的地方调用这个方法即可。

 

如果用DataSet,代码类似这样:

 

ContractedBlock.gif ExpandedBlockStart.gif Code
public int Update(DataSet dataSet, bool isStoredProc, bool removeCache, string[] cacheItemKeys)
ExpandedBlockStart.gifContractedBlock.gif        
{
                
int cnt = db.UpdateDataSet(dataSet, dataSet.Tables[0].TableName,
                PrepareCommand(insertCommand, InsertStoredProc, 
new PopulateParameters(PopulateInsertParamters), isStoredProc),
                PrepareCommand(updateCommand, UpdateStoredProc, 
new PopulateParameters(PopulateUpdateParamters), isStoredProc),
                PrepareCommand(deleteCommand, DeleteStoredProc, 
new PopulateParameters(PopulateDeleteParamters), isStoredProc),
                UpdateBehavior.Standard);

            
if (removeCache && cacheItemKeys != null)
ExpandedSubBlockStart.gifContractedSubBlock.gif            
{
                DataAccessUtil.UpdateCacheDependency(cacheItemKeys);
            }

            
return cnt;
        }

 

如果用实体类,代码类似这样:

 

ContractedBlock.gif ExpandedBlockStart.gif Code
protected bool ExecuteNonQuery(TEntity entity, string spName, PopulateParamters<TEntity> populateParamters, HandleReturnValue handleReturnValue, bool removeCache, string[] cacheKeys)
        {
            
int returnValue = -1;
            
try
            {
                Database db 
= DatabaseFactory.CreateDatabase();
                DbCommand cmd 
= db.GetStoredProcCommand(spName);

                
if (populateParamters != null)
                {
                    populateParamters(entity, db, cmd);
                }
                
if (handleReturnValue != null)
                {
                    db.AddParameter(cmd, 
"ReturnValue", DbType.Int32, ParameterDirection.ReturnValue, String.Empty, DataRowVersion.Default, null);
                }

                db.ExecuteNonQuery(cmd);
                returnValue 
= 0;
                
if (handleReturnValue != null)
                {
                    returnValue 
= DataAccessHelper.GetReturnValue(db, cmd);
                    handleReturnValue(returnValue, 
"");
                }
            }
            
catch
            {
                
throw;
            }

            
if (removeCache && cacheKeys != null && cacheKeys.Length > 0)
            {
                UpdateCacheDependency(cacheKeys);
            }

            
return (returnValue == 0);
        }

 

 

 

 

 

 

转载于:https://www.cnblogs.com/SilverLight/archive/2008/08/12/1265693.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值