Demo源码

写在前面的话

  写完这篇博客后,总觉得少了些什么,后来想了下,感觉自己只是把结果给亮了出来,自己为什么想到这么做,这个类库出生的缘由未详述,因此,在本段作下说明,如有不足之处,希望能和大家一起交流沟通。。,大家共同提高啊!

  我的想法很简单,我在拥有:

  1. 获取数据的方法

  并面对了下面的场景:

  1. 数据仅从数据库读取,不在程序中被修改
  2. 获取数据的方法在程序的很多地方被频繁的调用
  3. 我能把控数据的准确性对程序的影响

  我希望:可以有一个容器,让我在程序的入口处进行数据的初始化(丢给它获取数据的方法、key、过期时间)后,我能够在程序中其它任何地方通过key来获取到数据,并且,数据能够根据我设定的过期时间进行有效地更新!

  以此来达到:

  1. 缓存直接和方法进行绑定,而并非直接将具体值丢入缓存
  2. 避免在不同的页面声明相同的静态变量来获取相同的数据,减少代码量
  3. 统一在程序的入口管理所有的全局变量,提高代码的可维护性
  4. 避免频繁读取数据库,提高应用程序的性能

背景

  本来想聊聊本文产生的背景的,后来发现本码农词穷了。因此,直入主题,本文的工作是利用委托实现了一个全局的数据缓存仓库。

  这个类库接收4个参数:1 您要存储的数据的数据类型 2 获取需要存储数据的方法 3 过期的时间 4 读取该数据的唯一key

  这个类库就能够:根据key获取数据,数据通过执行您传入的获取数据的方法来获得,当上一次获取的时间过期后,会重新执行获取数据的方法以更新数据!

  推荐的使用方式:1 在应用程序的开端,进行所有需要缓存数据的初始化操作,统一管理所有的key;这样可以避免不必要的混乱

          2 在应用程序中需要使用的地方,直接通过key进行数据的获取,这样避免了在每个页面中写重复的代码,提高应用的效率

实现

  第一步,我们为需要存储的数据定义一个标准的数据结构:

  

    /// <summary>
/// 存储的数据结构
/// </summary>
/// <typeparam name="T">需要存储的数据的数据类型(string int ..)</typeparam>
public sealed class StoredDataInfo<T>
{ /// <summary>
/// 存储的数据
/// </summary>
public T Data { get; set; } /// <summary>
/// 获取需要存储的数据的方法
/// </summary>
public Func<T> GetDataMethod { get; set; } /// <summary>
/// 数据过期的时间
/// </summary>
public int TimeOfDuration { get; set; } /// <summary>
/// 数据上一次被更新的时间
/// </summary>
public DateTime LastModifyTime { get; set; } }

  以上代码一目了然,不用多说,大家都懂得。

  第二步,我们需要一个列表来存储需要的数据,因为我们会存储很多的数据

  

        //存储所有数据
/// <summary>
/// 存储所有数据
/// </summary>
private static readonly Dictionary<string, StoredDataInfo<T>> EntireStoredData = new Dictionary<string, StoredDataInfo<T>>();

  第三步,一个初始化数据的方法

        //初始化数据项
/// <summary>
/// 初始化数据项
/// </summary>
/// <param name="key"></param>
/// <param name="storedData"></param>
private static string InitStoredDataItem(string key, StoredDataInfo<T> storedData)
{
lock (lockObj)
{
if (EntireStoredData.ContainsKey(key))
{
return "key:" + key + " 已存在";
}
EntireStoredData.Add(key, storedData);
}
return "";
}

  第四步,根据key获取数据项的方法

        // 获取指定key的数据项
/// <summary>
/// 获取指定key的数据项
/// </summary>
/// <param name="key"></param>
/// <param name="isForcedRefresh">是否强制更新</param>
/// <returns></returns>
public static T GetData(string key, bool isForcedRefresh = false)
{
//不存在key
if (!HasKey(key))
{
#region string currKeys = "";
string currTType = "";
if (EntireStoredData.Any())
{
currKeys = string.Join(",", EntireStoredData.Keys.ToArray());
var v = EntireStoredData.First().Value.Data;
currTType = v.GetType().ToString();
}
throw new Exception(string.Format("无指定key:{0},当前池包含key集合{1},当前池类型:{2}", key, currKeys, currTType)); #endregion
} //根据key获取value
StoredDataInfo<T> sdi = EntireStoredData[key]; //判断是否过期
int timeOfDuration = sdi.TimeOfDuration;
DateTime lastModifyTime = sdi.LastModifyTime; if (!isForcedRefresh && DateTime.Now.AddMinutes(-timeOfDuration) <= lastModifyTime)
return sdi.Data; //重新更新数据
sdi.Data = sdi.GetDataMethod();
sdi.LastModifyTime = DateTime.Now; return sdi.Data;
}

使用

        static void Main(string[] args)
{
#region 数据缓存仓库测试 //key
const string key = "GetCurrDateKey";
//初始化仓库
DataWarehouse<string>.InitDataItem(key, GetCurrDate, ); //根据key获取值
Console.WriteLine(DataWarehouse<string>.GetData(key));
//休眠 等待过期
Thread.Sleep( * );
//再次根据key获取值
Console.WriteLine(DataWarehouse<string>.GetData(key)); Console.ReadLine(); #endregion
} /// <summary>
/// 获取时间
/// </summary>
/// <returns></returns>
private static string GetCurrDate()
{
return DateTime.Now.ToString();
}

  以上,做了一个很小的测试,存储一个当前时间的string类型的值,设定过期时间为1分钟,结果很显而易见。

  

利用委托实现自己的数据缓存仓库(附上Demo)的更多相关文章

  1. 利用js对象将iframe数据缓存, 实现子页面跳转后, 返回时不丢失之前填写的数据

    利用js对象将iframe数据缓存, 实现子页面跳转后, 返回时不丢失之前填写的数据 实现描述:将数据存放在js对象中, 然后放在父页面的document对象中, 在页面刷新的时候将父页面的值取出来, ...

  2. 利用decorator和descriptor进行数据缓存

    class cached_property(object): def __init__(self, func, name=None, doc=None): self.__name__ = name o ...

  3. C#利用委托跨线程更新UI数据

    转:http://www.2cto.com/kf/201206/136587.html 在使用C#的过程中,难免会用到多线程,而用多线程之后,线程如何与界面交互则是一个非常头疼的问题.其实不仅仅是界面 ...

  4. 【转】一个小工具类,利用shareObject把数据缓存

    原文链接:http://bbs.9ria.com/thread-284082-1-2.html 之前做一个数据缓存,就顺便把写入缓存,清除缓存,获取缓存都整理了一下,其中也做了些参考,个人水平有限,有 ...

  5. jQuery源码解读 - 数据缓存系统:jQuery.data

    jQuery在1.2后引入jQuery.data(数据缓存系统),主要的作用是让一组自定义的数据可以DOM元素相关联——浅显的说:就是让一个对象和一组数据一对一的关联. 一组和Element相关的数据 ...

  6. cache应用(asp.net 2.0 SQL数据缓存依赖 [SqlCacheDependency ] )

    Asp.net 2.0 提供了一个新的数据缓存功能,就是利用sql server2005 的异步通知功能来实现缓存 1.首先在sqlserver2005 中创建一个test的数据库. 在SQL Ser ...

  7. 利用Flume将MySQL表数据准实时抽取到HDFS

    转自:http://blog.csdn.net/wzy0623/article/details/73650053 一.为什么要用到Flume 在以前搭建HAWQ数据仓库实验环境时,我使用Sqoop抽取 ...

  8. iOS开发网络篇—数据缓存

      iOS开发网络篇—数据缓存 一.关于同一个URL的多次请求 有时候,对同一个URL请求多次,返回的数据可能都是一样的,比如服务器上的某张图片,无论下载多少次,返回的数据都是一样的. 上面的情况会造 ...

  9. ssm+redis 如何更简洁的利用自定义注解+AOP实现redis缓存

    基于 ssm + maven + redis 使用自定义注解 利用aop基于AspectJ方式 实现redis缓存 如何能更简洁的利用aop实现redis缓存,话不多说,上demo 需求: 数据查询时 ...

随机推荐

  1. Myeclipse发布第一个jsp页面及web project部署到tomcat上的几种方法

    菜鸟日记: 1:new web project: 2:fix the visiting  path of the tomcat,打开在安装目录下conf目录中的server.xml,在</Hos ...

  2. Android(java)学习笔记109:Java中输入和输出流概念

     程序在内存中运行,文件在磁盘上,把文件从磁盘上读入内存中来,当然是输入流了,   反之,把内存中的数据写到磁盘上的文件里面去就是输出.通常都是这样的,用了过滤流的情况复杂一些,则另当别论.

  3. Android(java)学习笔记107:Relativelayout相对布局

    1. Relativelayout相对布局案例: 我们看看案例代码,自己心领神会: <?xml version="1.0" encoding="utf-8" ...

  4. 第010课_掌握ARM芯片时钟体系

    from:第010课_掌握ARM芯片时钟体系 第001节_S3C2440时钟体系结构 S3C2440是System On Chip(SOC),在芯片省不仅仅有CPU,还有一堆外设. 至于有哪些外设,可 ...

  5. 【转】Popclip的JSON格式化扩展

    http://liuyunclouder.github.io/2016/09/29/JSONizer:Popclip的JSON格式化扩展 作为一个MAC党,不好好利用MAC的神兵利器,简直就是罪过.A ...

  6. iOS中的数据存储方式_SQLite3

    优点: 1) SQLite是一款轻型的嵌入式数据库; 2) 它占用资源非常的低,在嵌入式设备中,可能只需要几百K的内存就够了 3) 它的处理速度比Mysql.PostgreSQL这两款著名的数据库都还 ...

  7. Kenneth A.Lambert著的数据结构(用python语言描述)的第一章课后编程答案

    第6题:工资部门将每个支付周期的雇员信息的列表保存到一个文本文件, 每一行的格式:<last name><hourly wage><hours worked> 编写 ...

  8. 救援(BFS)

    题目描述: 在你的帮助下,Oliver终于追到小X了,可有一天,坏人把小X抓走了.这正是Oliver英雄救美的时候.所以,Oliver又找到哆啦A梦,借了一个机器,机器显示出一幅方格地图,它告诉Oli ...

  9. Mycat高可用解决方案二(主从复制)

    Mycat高可用解决方案二(主从复制) 系统部署规划 名称 IP 主机名称 用户名/密码 配置 mysql主节点 192.168.199.110 mysql-01 root/hadoop 2核/2G ...

  10. linux文件属性软硬链接知识

    链接的概念 在linux系统中,链接可分为两种:一种为硬链接,另一种为软链接或符号链接.在默认不带参数的情况下,执行ln命令创建的链接是硬链接. 如果使用ln  -s创建链接则为软链接,前面文件类型为 ...