Prism enterprise Cache Manager

本文通过分析缓存管理器的一致性问题,展示了其配置与使用方法。文章深入探讨了缓存项过期机制及线程安全问题,并提供了具体代码示例。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

Caching is a advanced topic if you decied to develope some enterprise level application. There are a case studied in this page "Cache and DataBase synchronization through SqlDependency". 

 

 

A feel of the CacheManager

 

However, in this article, I am going to show a flavor of the CacheManager by analysing a consistence issue regarding CacheManager. The code and the configuration is based on "Microsoft Enterprise Library Caching Application Block not thread safe?"

 

 

First let see the configuration in a file called EnterpriseCacheManager.config file.

 

 

 

<configuration>
  <configSections>
    <section name="cachingConfiguration" type="Microsoft.Practices.EnterpriseLibrary.Caching.Configuration.CacheManagerSettings, Microsoft.Practices.EnterpriseLibrary.Caching, Version=4.1.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" />
  </configSections>
  <cachingConfiguration defaultCacheManager="Cache Manager">
    <cacheManagers>
      <add expirationPollFrequencyInSeconds="1" maximumElementsInCacheBeforeScavenging="1000"
      numberToRemoveWhenScavenging="10" backingStoreName="Null Storage"
      type="Microsoft.Practices.EnterpriseLibrary.Caching.CacheManager, Microsoft.Practices.EnterpriseLibrary.Caching, Version=4.1.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35"
      name="Cache Manager" />
    </cacheManagers>
    <backingStores>
      <add encryptionProviderName="" type="Microsoft.Practices.EnterpriseLibrary.Caching.BackingStoreImplementations.NullBackingStore, Microsoft.Practices.EnterpriseLibrary.Caching, Version=4.1.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35"
      name="Null Storage" />
    </backingStores>
  </cachingConfiguration>
</configuration>

 

 

 

and the source code that manipulate the CacheManager is like this : 

 

 

 

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.Practices.EnterpriseLibrary.Caching;
using Microsoft.Practices.EnterpriseLibrary.Common.Configuration;
using Microsoft.Practices.EnterpriseLibrary.Caching.Expirations;

namespace EnterpriseCacheManager
{
  class Program
  {
    public static ICacheManager cacheManager = null;

    private static void InitializeCacheManager()
    {
      if (cacheManager == null)
      {
        var fileSource = new FileConfigurationSource("EnterpriseCacheManager.config");
        var factory = new CacheManagerFactory(fileSource);
        cacheManager = factory.CreateDefault();
      }
    }
    
    static void Main(string[] args)
    {
      Test2();
    }

    private static void Test1()
    {
      InitializeCacheManager();

      while (true)
      {
        System.Threading.Thread.Sleep(1000);
        var key = new Random().Next(3).ToString();
        string value = "";

        lock (cacheManager)
        {
          if (!cacheManager.Contains(key))
          {
            cacheManager.Add(key, key, CacheItemPriority.Normal, null, new SlidingTime(TimeSpan.FromSeconds(5)));
            value = (string)cacheManager.GetData(key);
          }
        }

        Console.WriteLine("{0} ---> '{1}'", key, value);
      }
    }


    static void Test2()
    {
      /**
       *
       * As explained in the reply from Tuzo, in his own word. &lt;quote&gt;http://stackoverflow.com/questions/1302643/microsoft-enterprise-library-caching-application-block-not-thread-safe/&lt;quote&gt;
       * What you are seeing is that your CacheItem has expired due to the 5 second SlidingTime expiration.

Before returning the cached value, the GetData method performs a check to see if the CacheItem has expired. If it has expired, the CacheItem is removed from the cache and null is returned. However, the call to Contains will return true because the CacheItem is in the cache even though it's expiration may have elapsed. This seems to be by design. With that in mind, it would be wise not to cache a null value to represent no data since you would not be able to discern an expired CacheItem from an actual cached value of null.

Assuming that you do not cache a null value then Luke's solution should suit you:
       */
      InitializeCacheManager();

      while (true)
      {
        System.Threading.Thread.Sleep(1000);
        var key = new Random().Next(3).ToString();

        string value = "";

        lock (cacheManager)
        {
          value = cacheManager.GetData(key) as string;
          if (value == null)
          {
            value = key;
            cacheManager.Add(key, value, CacheItemPriority.Normal, null, new SlidingTime(TimeSpan.FromSeconds(5)));
          }
          value = cacheManager.GetData(key) as string;
        }

        Console.WriteLine("{0} ---> '{1}'", key, value);
      }
    }
  }
}
 

 

If you run Test1(), then you might see something like this in the output.

 

 

2 --> '2'
1 --> '1'
2 --> '2'
0 --> '0'
2 --> '2'
0 --> '0'
1 --> ''
0 --> '0'
1 --> '1'
2 --> ''
0 --> '0'
2 --> '2'
0 --> '0'
1 --> ''
2 --> '2'
1 --> '1'
Press any key to continue . . .

 

 

What CacheManager can lend itself to?

 

CacheManager can have the following. 

 

GetDate

StoreData

Flush

Remove

Expiration time on CacheItem

Expiration Strategy on cacheItem (FileDependency (when file is updated), AbsoluteTime, NeverExpired, SlidingTime (time window))

...

 

 

 

NOTE: This topic may deserve further exploration.

 

 

 

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值