性能优化之读写分离二

上文我们已经说了一些关于读写分离的概念。这篇博客,就大致的写了一个简单的demo 来表现出这种设计思想。

写数据
新建一个类为DataWriter,该类主要用于通过WCF从服务端获取数据。

 protected Dictionary<string, double> originalDataCache = new Dictionary<string, double>();//存放缓存数据
        public Dictionary<string, double> WriteTypeData()
        {
            try
            {
                var dt = QueryServiceFactory.GetDataService(CommonConstants.ServiceEndpointName).GetCurrentData();//获取源数据
                if (dt == null || dt.Rows.Count <= 0)
                {
                    return new Dictionary<string, double>();
                }
                string s_ID;
                lock (this)
                {
                    foreach (DataRow item in dt.Rows)
                    {
                        s_ID = item[IDColumnName].ToString().Trim();
                        if (!string.IsNullOrEmpty(s_ID))
                        {
                            if (originalDataCache.ContainsKey(s_ID))
                            {
                                originalDataCache[s_ID] = Convert.ToDouble(item[ValueColumnName]);
                            }
                        }
                    }

                }

                return originalDataCache;
            }
            catch (Exception) { }
            return new Dictionary<string, double>();
        }

二 存缓存
新建一个类为DataCacheManage,该类主要用于将数据放到缓存中,同时能和读数据的类共享缓存数据。

        Dictionary<string, double> DataCache = new Dictionary<string, double>();
        /// <summary>
        /// 将相应数据放到缓存中
        /// </summary>
        /// <param name="count"></param>
        private void WriteDataCache()
        {
            try
            {
                temDataCache = DataWriter.WriteData();
                lock (DataCache)
                {
                    DataCache = temDataCache;
                }
            }
            catch (Exception) { }
        }

三 从缓存中读取数据

  public void AccessData(Dictionary<string, double> temDic)
        {
            if (temDic==null||temDic.Count <= 0) return;
            try
            {
                foreach (string key in temDic.Keys)
                {
                    var ucValue = StyleFile.StaticStyleValue.GetUcValue(key);
                    ucValue.RealTimeData = temDic[key];
                }
            }
            catch (Exception)
            {
            }

        }

中间的衔接部分没有细致的写。相信读者可以自行联通起来。

到这一步的,相当于我们已经做好了准备的工作。
即:一方面能将数据源的数据写到缓存。另一方面能从缓存中读取数据更新界面。下一步我们就是安排两个环节做到相互独立不干扰。
于是开启了两个线程。

1)开启一个读线程

        #region 界面显示实时数据功能-读数据缓存
        /// <summary>
        /// 刷新界面
        /// </summary>
        private void StartDelAccessDataCache()
        {
            realTimeAccessThreadDelgate realTimeAccessDel = delegate()
            {
                writeTimer.Start();
                writeTimer.Tick += new EventHandler(StartAccessDataCache);
                writeTimer.Interval = TimeSpan.FromMilliseconds(800);
            };

            lock (refreshAccessLock)
            {
                writeTimer.Dispatcher.BeginInvoke(DispatcherPriority.Normal, realTimeAccessDel);
            }
        }

        private void StartAccessDataCache(object sender, EventArgs e)
        {
            if (!isAccessingData)//标志位控制如果下面的程序没有执行完即使当前又触发一次该事件也不予执行
            {
                isAccessingData = true;
                accessCounter = accessCounter == timerInfo.RefreshCycle + 1 ? 1 : accessCounter;
                ManageAccessDataCache(accessCounter);
                writeCounter = writeCounter + 1;
                isAccessingData = false;
            }
        }


        private void ManageAccessDataCache(int timerUICount)
        {
            try
            {
                if (timerUICount % timerInfo.WindRefreshInterval == 0)//如果到了更新间隔值
                {
                    realTimeDataAccess.WindAccessData(DataCache);
                }
            }
            catch (Exception)
            {

            }
        }

2)开启一个读线程

   /// <summary>
        /// 开启一个计时器实时写缓存
        /// </summary>
        private void StartDelWriteDataCache()
        {
            realTimeWriteThreadDelgate realTimeWriteDel = delegate()
            {
                realTimeRefreshDataTimer.Start();
                realTimeRefreshDataTimer.Tick += new EventHandler(StartWriteDataCache);
                realTimeRefreshDataTimer.Interval = TimeSpan.FromMilliseconds(400);
            };
            lock (refreshAccessLock)
            {
                realTimeRefreshDataTimer.Dispatcher.BeginInvoke(DispatcherPriority.Normal, realTimeWriteDel);
            }
        }

        /// <summary>
        /// 通过计数器计数,控制写数据的过程
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void StartWriteDataCache(object sender, EventArgs e)
        {
            if (!isWrittingData)//标志位控制如果下面的程序没有执行完即使当前又触发一次该事件也不予执行
            {
                isWrittingData = true;

                writeCounter = writeCounter == timerInfo.RefreshCycle + 1 ? 1 : writeCounter;
                ManageWriteDataCache(writeCounter);
                writeCounter = writeCounter + 1;

                isWrittingData = false;
            }
        }

如此,我们便做完了。篇幅有限,细节的定义和衔接都没有在博客中写出来,不过重要的还是对读写分离这样一个概念的认识和理解。对于之后的大数据的设计非常的有帮助。当然,关联到具体的项目中去的话,还要根据实时性的要求去优化数据源和数据缓存如何能在更小的时间单位里保持一致。也要考虑到对数据块既有读操作也有写操作时,应该在哪里加锁更合适。以上,抛砖引玉。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值