昆明光标科技有限公司

.net 4.0 自定义本地缓存策略的不同实现

在分布式系统的开发中,为了提高系统运行性能,我们从服务器中获取的数据需要缓存在本地,以便下次使用,而不用从服务器中重复获取,有同学可能要问,为什么不使用 分布式缓存等,注意,服务器端肯定是考虑到扩展,可以使用各种缓存方法,但数据来到本地,在客户端(各种形式的客户端)是否了需要进行缓存以提升性能呢,回答是肯定的。

在.net 4 中,框架增加了System.Runtime.Caching 名称空间,用于支持缓存,虽然它可以用于服务器端,也可用于本地。

关于缓存在.net 中如何使用,它的概念,可以参考:

http://www.dotblogs.com.tw/larrynung/archive/2010/11/26/19746.aspx

关于如何自定义缓存策略的实现,可参考:

http://www.dotblogs.com.tw/larrynung/archive/2013/06/12/105458.aspx

缓存什么时候失效的检查是自定义的的关键,如以上示例所示,使用 Timer 组件来触发检查事件,其局限性为:必须引用System.Windows.Form.dll类库,并且性能也消耗也大,可参考:Timer 与 Thread 线程的性能比较。

这是我的实现1:

    internal class PartyChangeMonitor : ChangeMonitor

    {

        #region 私有变量
        private string _uniqueID = Guid.NewGuid().ToString();
        private DateTime _MonitorTime;
        private int _PartyID;
        private int _CheckInterval;

        #endregion

        #region Public Property
        public override string UniqueId
        {
            get { return _uniqueID; }
        }
        #endregion

        #region Constructor
        public PartyChangeMonitor(int partyID, int checkInterval)
        {
            _PartyID = partyID;
            _CheckInterval = checkInterval * 1000;
            _MonitorTime = DateTime.Now;
            isStoped = false;

            this.StartDaemon();
            InitializationComplete();
        }
        #endregion

        #region Protected Method
        protected override void Dispose(bool disposing)
        {

        }
        #endregion

        #region 心跳监控
        Thread thrDaemon;
        bool isStoped = true;
        //登录时启动,开始心跳检测
        void StartDaemon()
        {
            //System.Threading.ThreadPool.get
            this.thrDaemon = new Thread(new ThreadStart(this.Daemon));
            thrDaemon.Start();
        }
        /// <summary>
        
/// 监视任务,如果已过期,则停止检测
        
/// </summary>
        void Daemon()
        {
            while (!this.isStoped)
            {
                Thread.Sleep(_CheckInterval);

                DateTime _LastUpdatedTime = Party.GetLastUpdatedTime(_PartyID);
                if (_LastUpdatedTime > _MonitorTime)
                {
                    OnChanged(_LastUpdatedTime);
                    isStoped = true;
                }
            }
        }
        #endregion
    }

以上实现有个问题是,每个检查策略都会开启一个线程,这样如果有1000个策略呢,10000个呢,CPU在线程间切换的性能消耗就把机器拖跨,这个实现虽然比使用Timer组件要好很多,但离真正的可用还是差哪么一步,因此,才有了以下实现: 

这是我的实现2: 

    internal class PartyChangeMonitor2 : ChangeMonitor 

    {
        #region 私有变量
        private string _uniqueID ;
        private DateTime _MonitorTime;
        private int _PartyID;
        #endregion

        #region Public Property
        public override string UniqueId
        {
            get { return _uniqueID; }
        }
        #endregion

        #region Constructor
        public PartyChangeMonitor2(int partyID, int checkInterval)
        {            
            _uniqueID = Guid.NewGuid().ToString();

            _PartyID = partyID;
            _MonitorTime = DateTime.Now;

            LocalCache.RegisterCheckHandler(UniqueId,CheckExpired, checkInterval);
            InitializationComplete();
        }
        #endregion

        #region Protected Method
        protected override void Dispose(bool disposing)
        {
            LocalCache.RemoveCheckHandler(this.UniqueId);
            base.Dispose();
        }
        #endregion

        #region 过期检测
        /// <summary>
        
/// 如果已过期,则停止检测
        
/// </summary>
        
/// <returns>true 数据已过期,可以移除检测,false 数据有效,要继续检测</returns>
        public bool CheckExpired()
        {
            DateTime _LastUpdatedTime = Party.GetLastUpdatedTime(_PartyID);
            if (_LastUpdatedTime > _MonitorTime)
            {
                OnChanged(_LastUpdatedTime);
                return true;
            }
            else
            {
                return false;
            }
        }
        #endregion
    }

 此实现无论有多少 缓存策略,都只有一个守护线程在工作,最大程度提高了系统性能与可用性。

posted @ 2013-12-04 22:25  杨义金  阅读(878)  评论(0编辑  收藏  举报
昆明光标科技有限公司