TinyFrame升级之五:全局缓存的设计及实现

在任何框架中,缓存都是不可或缺的一部分,本框架亦然。在这个框架中,我们的缓存分为两部分:内存缓存和单次请求缓存。简单说来,就是一个使用微软提供的MemoryCache做扩展,并提供全局唯一实例;另一个使用微软提供的HttpContextBase做扩展,用户每发送一次请求,HttpContextBase都会被关联创建。先来看下接口约束:

   1:  using System;
   2:  using System.Collections.Generic;
   3:  using System.Linq;
   4:  using System.Text;
   5:   
   6:  namespace TinyFrame.Framework.Caching
   7:  {
   8:      public interface ICacheManager
   9:      {
  10:          //根据key获取缓存对象
  11:          T Get<T>(string key);
  12:   
  13:          //设置缓存对象
  14:          void Set(string key, object data, int cacheTime);
  15:   
  16:          //查询key是否被缓存
  17:          bool IsSet(string key);
  18:   
  19:          //从缓存移除
  20:          void Remove(string key);
  21:   
  22:          //缓存移除匹配
  23:          void RemoveByPattern(string pattern);
  24:   
  25:          //清空所有缓存
  26:          void Clear();
  27:      }
  28:  }

 

方法不多,但是包含了缓存的增删查。其中Get泛型方法可以通过Key返回缓存对象;Set方法可以添加缓存;IsSet方法可以检测缓存是否存在;Remove方法可以清除已有的单个缓存;RemoveByPattern可以通过正则匹配清除缓存;Clear方法则清除全部缓存。

首先是MemoryCacheManager的实现:

   1:  using System;
   2:  using System.Collections.Generic;
   3:  using System.Linq;
   4:  using System.Text;
   5:  using System.Runtime.Caching;
   6:  using System.Text.RegularExpressions;
   7:   
   8:  namespace TinyFrame.Framework.Caching
   9:  {
  10:      public class MemoryCacheManager:ICacheManager
  11:      {
  12:          protected ObjectCache Cache
  13:          {
  14:              get { return MemoryCache.Default; }
  15:          }
  16:   
  17:          public T Get<T>(string key)
  18:          {
  19:              return (T)Cache[key];
  20:          }
  21:   
  22:          public void Set(string key, object data, int cacheTime)
  23:          {
  24:              if (data == null)
  25:                  return;
  26:              var policy = new CacheItemPolicy();
  27:              policy.AbsoluteExpiration = DateTime.Now + TimeSpan.FromMinutes(cacheTime);
  28:              Cache.Add(new CacheItem(key,data),policy);
  29:   
  30:          }
  31:   
  32:          public bool IsSet(string key)
  33:          {
  34:              return Cache.Contains(key);
  35:          }
  36:   
  37:          public void Remove(string key)
  38:          {
  39:              Cache.Remove(key);
  40:          }
  41:   
  42:          public void RemoveByPattern(string pattern)
  43:          {
  44:              var regex = new Regex(pattern, RegexOptions.Singleline
  45:                                              | RegexOptions.Compiled
  46:                                              | RegexOptions.IgnoreCase);
  47:              var keysToRemove = new List<string>();
  48:              foreach (var item in Cache)
  49:                  if (regex.IsMatch(item.Key))
  50:                      keysToRemove.Add(item.Key);
  51:   
  52:              foreach (string key in keysToRemove)
  53:              {
  54:                  Remove(key);
  55:              }
  56:          }
  57:   
  58:          public void Clear()
  59:          {
  60:              foreach (var item in Cache)
  61:              {
  62:                  Remove(item.Key);
  63:              }
  64:          }
  65:      }
  66:  }

 

然后是PerRequestCacheManager的实现:

   1:  using System;
   2:  using System.Collections.Generic;
   3:  using System.Linq;
   4:  using System.Text;
   5:  using System.Web;
   6:  using System.Collections;
   7:  using System.Text.RegularExpressions;
   8:   
   9:  namespace TinyFrame.Framework.Caching
  10:  {
  11:      public class PerRequestCacheManager : ICacheManager
  12:      {
  13:          public PerRequestCacheManager(HttpContextBase context)
  14:          {
  15:              this.context = context;
  16:          }
  17:   
  18:          private readonly HttpContextBase context;
  19:   
  20:          protected virtual IDictionary GetItems()
  21:          {
  22:              if (context != null)
  23:                  return context.Items;
  24:   
  25:              return null;
  26:          }
  27:   
  28:          public T Get<T>(string key)
  29:          {
  30:              var items = GetItems();
  31:              if (items == null)
  32:                  return default(T);
  33:   
  34:              return (T)items[key];
  35:          }
  36:   
  37:          public void Set(string key, object data, int cacheTime)
  38:          {
  39:              var items = GetItems();
  40:              if (items == null)
  41:                  return;
  42:   
  43:              if (data != null)
  44:              {
  45:                  if (items.Contains(key))
  46:                      items[key] = data;
  47:                  else
  48:                      items.Add(key, data);
  49:              }
  50:          }
  51:   
  52:          public bool IsSet(string key)
  53:          {
  54:              var items = GetItems();
  55:              if (items == null)
  56:                  return false;
  57:   
  58:              return items[key] != null;
  59:          }
  60:   
  61:          public void Remove(string key)
  62:          {
  63:              var items = GetItems();
  64:              if (items == null)
  65:                  return;
  66:   
  67:              items.Remove(key);
  68:          }
  69:   
  70:          public void RemoveByPattern(string pattern)
  71:          {
  72:              var items = GetItems();
  73:              if (items == null)
  74:                  return;
  75:   
  76:              var enumerator = items.GetEnumerator();
  77:              var regex = new Regex(pattern, RegexOptions.Singleline
  78:                                            | RegexOptions.Compiled
  79:                                            | RegexOptions.IgnoreCase);
  80:              var keysToRemove = new List<string>();
  81:              while (enumerator.MoveNext())
  82:              {
  83:                  if (regex.IsMatch(enumerator.Key.ToString()))
  84:                  {
  85:                      keysToRemove.Add(enumerator.Key.ToString());
  86:                  }
  87:              }
  88:   
  89:              foreach (string key in keysToRemove)
  90:              {
  91:                  items.Remove(key);
  92:              }
  93:          }
  94:   
  95:          public void Clear()
  96:          {
  97:              var items = GetItems();
  98:              if (items == null)
  99:                  return;
 100:   
 101:              var enumerator = items.GetEnumerator();
 102:              var keysToRemove = new List<string>();
 103:              while (enumerator.MoveNext())
 104:              {
 105:                  keysToRemove.Add(enumerator.Key.ToString());
 106:              }
 107:   
 108:              foreach (string key in keysToRemove)
 109:              {
 110:                  items.Remove(key);
 111:              }
 112:          }
 113:      }
 114:  }

 

二者的实现方式差不多。这里我就不做过多的解释了。

如果想使用的话,直接在Autofac容器中注册一下就行了。在这次演示中,我们使用MemoryCacheManager来做缓存容器。

这里我以一个分页为例:

   1:  string BookPaggerKey = "Books-{0}-{1}-{2}-{3}";
   2:          //分页查询
   3:          public IList<Book> GetBooksPagger(int pageCount
   4:                                          , int currentIndex
   5:                                          , out int totalCount
   6:                                          , string propertyName=""
   7:                                          , string propertyValue=""
   8:                                          )
   9:          {
  10:              IQueryable<Book> bookList = null;
  11:              int skipRows = 0;
  12:              if (currentIndex > 0) skipRows = currentIndex * pageCount;
  13:   
  14:              if (!string.IsNullOrEmpty(propertyName))
  15:                  bookList = GetBooksByConstruct(propertyName, propertyValue);
  16:              else
  17:                  bookList = bookRepository.GetMany(m => m.ID >= 0);
  18:              totalCount = bookList.Count();
  19:              
  20:              //return bookList.OrderBy(p => p.ID).Skip(skipRows).Take(pageCount).ToList();
  21:              string key = string.Format(BookPaggerKey, pageCount, currentIndex, propertyName, propertyValue);
  22:   
  23:              return cacheManager.Get(key, () => bookList.OrderBy(p => p.ID).Skip(skipRows).Take(pageCount).ToList());
  24:          }

第1行:定义了一个Cache的Key,用于标识保存ID

第23行:利用get方法检查缓存容器,如果缓存中数据不存在,则将查询数据添加到缓存;否则直接从缓存中拿出数据来。

我们来看看效果:

首先打开页面,我们换换页,目的是让页面被缓存住:

QQ截图20140415223519

然后我们打开SQL的SQL Server Profile来进行追踪,现在,我们点击页面的刷新按钮,看看测试效果 :

QQ截图20140415223805

当我们连续刷新页面好几次,但是并未见到有新的分页查询被追踪到,说明我们的数据被缓存住了。

最后我们加个断点调试一下缓存对象,可以找到被缓存的数据:

QQ截图20140415223959

转载于:https://www.cnblogs.com/scy251147/p/3667541.html

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/420995.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

问题思维导向

杨淼信息与计算机科学 跆拳道国家一级教练员 曾经tricking爱好者3 人赞同了该回答一个不算建议的建议 直接看&#xff0c;看到不懂的就查相应的知识&#xff08;据说牛人都靠wiki活着&#xff09;。 知识当有需求的时候&#xff0c;才会学的更快。 觉得这样做的好处是&#xff…

【Mail】telnet收发邮件过程

文章原址&#xff1a;http://www.cnblogs.com/h--d/p/6125993.html 作者写的真棒&#xff0c;按照步骤一步一步都可执行&#xff0c;我是在centos7服务器下进行的实验&#xff0c;命令完全和下面一样&#xff0c;注意的地方是&#xff1a; 1&#xff0c;centos7要安装telnet&a…

入门训练 Fibonacci数列

http://lx.lanqiao.org/problem.page?gpidT4入门训练 Fibonacci数列 时间限制&#xff1a;1.0s 内存限制&#xff1a;256.0MB问题描述Fibonacci数列的递推公式为&#xff1a;FnFn-1Fn-2&#xff0c;其中F1F21。 当n比较大时&#xff0c;Fn也非常大&#xff0c;现在我们想知…

python模块与包的导入

一&#xff0c;模块 1&#xff0c;下面是hello.py脚本(模块)&#xff0c;有两求Fibonacci的函数. def fib1():a, b 0, 1print(0-10内:)while a < 10:print(a, end )a, b b, a bprint()def fib2(n):a, b 0, 1L []while a < n:L.append(a)a, b b, a bprint(L)retu…

第11章 进入保护模式

对照代码重点理解一下三个要点&#xff1a; 1,从实模式到保护模式的整体过程&#xff1b; 2&#xff0c;实模式怎样安装GDT&#xff1b; 3&#xff0c;从实模式怎样过渡到安全模式&#xff1b; 4&#xff0c;安全模式怎样寻址&#xff1b; 代码如下&#xff1a; ;代码清单1…

ASP.NET学习笔记之操作过滤器

转载于:https://www.cnblogs.com/kevin1988/p/3684442.html

第12章 存储器的保护

学习32位保护模式明显感觉比16位实模式复杂一些&#xff0c;其实两者之间所做的事情是一样的&#xff0c;无非是对内存的各种操作&#xff0c;对栈的各种操作&#xff0c;但是手段不一样&#xff0c;实模式是野蛮的&#xff0c;可以在任意地方读写&#xff08;比如代码区&#…

with open的使用

1, open(‘file’, mode) 第一个参数是包含文件名的字符串。第二个参数是另一个字符串&#xff0c;其中包含一些描述文件使用方式的字符。mode 可以是 ‘r’&#xff0c;表示文件只能读取&#xff0c;‘w’ 表示只能写入&#xff08;已存在的同名文件会被删除&#xff09;&…

Android硬件抽象层(HAL)概要介绍和学习计划 1转

最近和另外一家开发公司涉及到合作,一直希望了解Android从Linux到App整个架构和流程,那家开发工程师也不断提供帮助,不过如果借助后面几篇博客,相对系统和完整的可以了解更加清晰, <博客:http://blog.csdn.net/luoshengyang/article/details/6567257> Android的硬件抽象层…

第13章 程序的动态加载和执行(二,用户代码)

弄清楚两个问题&#xff0c;这段应用代码就容易读懂了&#xff1a; 1&#xff0c;核心代码是如何把指针指到这里的&#xff1b; 2&#xff0c;这段代码是如何使用内存的&#xff1b; 读这个代码的时候&#xff0c;可以类比我们平时写的练习小程序&#xff0c;以C程序为例&am…

【雷军】给程序员的五点建议--如何成为编程高手并以此创业

除非特别注明&#xff0c;鸡啄米文章均为原创转载请标明本文地址&#xff1a;http://www.jizhuomi.com/career/286.html写在前面&#xff1a;此篇文章出自雷军之手&#xff0c;是他为软件开发2.0技术大会准备的演讲稿&#xff0c;但由于某些原因没有派上用场。这里跟大家分享下…

计算机网络重要机制(一)可靠数据传输

操作系统&#xff0c;计算机网络都属于计算机系统&#xff0c;为了使得整个系统运行起来&#xff0c;人们根据当时的硬件条件和理论认识设计了各种的算法&#xff08;也可以叫机制&#xff09;&#xff0c;这些机制有些被抛弃&#xff0c;有些被进化。所以操作系统、计算机网络…

命名空间和作用域

一&#xff0c;namespace namespace是名字到对象的映射&#xff0c;python里面的大部分命名空间由字典实现。如果有性能问题&#xff0c;会更改。 命名空间的举例 •存放内置函数的集合&#xff08;abs()这种函数&#xff0c;和内建的异常&#xff09; •模块中的全局名称 •函…

python类

一&#xff0c;类 1&#xff0c;类是摸板&#xff0c;里面有组合数据&#xff0c;实现功能的方法。 2&#xff0c;类里面有可以改变自身的方法__init__函数 3&#xff0c;类和模块类似&#xff0c;运行时创建&#xff0c;创建后修改 4&#xff0c;类成员通常是public&#xff…

Web Form要“jquery”ScriptResourceMapping。请添加一个名为 jquery (区分大小写)的 ScriptResourceMapping。”的解决办法。...

1.先将aspnet.scriptmanager.jquery.dl 复制到bin (网站根目录下的bin文件夹找不到&#xff0c;看看下面的图片中点击[显示所有文档]) 文件夹下。 2.在网站根目录下scripts文件夹,向里边添加jquery-1.7.2.min.js和jquery-1.7.2.js(可根据自己需要使用不同的版本&#xff09;…

python继承多重继承

一&#xff0c;基本语法 class MyClass(BaseClass):def __init__(self):print(...)class MyDefineClass(object):def __init__(self):print(继承自object类)MyDefineClass.__init__(None) # 属性访问 me MyDefineClass() # 实例对象 继承自object类 继承自object类 二&#x…

Windows XP系统安装SQL Server 2005(开发版)图解

转自Windows XP系统安装SQL Server 2005(开发版)图解 安装前提:由于有些从网上的下载的项目需要导入SQL Server 2005的数据文件&#xff0c;因此&#xff0c;今天便安装了这个数据库&#xff0c;我的系统中已经安装了SQL Server2000所以是在它之上安装SQL Server2005的。 一、数…

用turtle画各种各样的数学图形

ps&#xff0c;用turtle导入小海龟来画图。画图代码都要导入海龟库哦&#xff0c;见下面第一行。 import turtle as t直线 # 画直线 def draw_line():pen t.Pen()pen.fd(200) # 直线默认水平方向 draw_line() 画正方形 def draw_square():pen t.Pen()for i in range(4): …

实验3 系统调用

系统调用 实验目的 建立对系统调用接口的深入认识掌握系统调用的基本过程能完成系统调用的全面控制为后续实验做准备 实验内容 此次实验的基本内容是&#xff1a;在Linux 0.11上添加两个系统调用&#xff0c;并编写两个简单的应用程序测试它们。 iam() 第一个系统调用是iam()&a…