1. using System;
  2. using System.Collections.Generic;
  3. using System.Threading.Tasks;
  4. namespace System
  5. {
  6.  
  7. /// <summary>
  8. /// 一个接口,表示缓存
  9. /// </summary>
  10. /// <typeparam name="TKey"></typeparam>
  11. /// <typeparam name="TValue"></typeparam>
  12. public interface ICache<TKey, TValue> : IEnumerable<KeyValuePair<TKey, TValue>>
  13. {
  14. /// <summary>
  15. /// 获取当前缓存的数量
  16. /// </summary>
  17. int Count { get; }
  18.  
  19. IEnumerable<TKey> Keys { get; }
  20.  
  21. /// <summary>
  22. /// 是否包含键
  23. /// </summary>
  24. bool ContainsKey(TKey key);
  25.  
  26. /// <summary>
  27. /// 查询缓存
  28. /// </summary>
  29. /// <param name="key"></param>
  30. /// <param name="factory"></param>
  31. /// <returns></returns>
  32. TValue Get(TKey key, Func<TValue> factory);
  33.  
  34. ///// <summary>
  35. ///// 查询缓存
  36. ///// </summary>
  37. ///// <param name="key"></param>
  38. ///// <returns></returns>
  39. //TValue Get(TKey key);
  40.  
  41. /// <summary>
  42. /// 查询缓存
  43. /// </summary>
  44. /// <param name="key"></param>
  45. /// <param name="factory"></param>
  46. /// <returns></returns>
  47. Task<TValue> GetAsync(TKey key, Func<Task<TValue>> factory);
  48.  
  49. ///// <summary>
  50. ///// 查询缓存
  51. ///// </summary>
  52. ///// <param name="key"></param>
  53. ///// <returns></returns>
  54. //Task<TValue> GetAsync(TKey key);
  55.  
  56. /// <summary>
  57. /// 获取数据,没有返回默认值
  58. /// </summary>
  59. /// <param name="index"></param>
  60. /// <returns></returns>
  61. TValue this[TKey key] { get; set; }
  62.  
  63. /// <summary>
  64. /// 清空缓存
  65. /// </summary>
  66. void Flush();
  67.  
  68. /// <summary>
  69. /// 更新缓存
  70. /// </summary>
  71. /// <param name="key"></param>
  72. /// <param name="value"></param>
  73. /// <returns></returns>
  74. bool Update(TKey key, TValue value);
  75.  
  76. /// <summary>
  77. /// 添加缓存
  78. /// </summary>
  79. /// <param name="key"></param>
  80. /// <param name="value"></param>
  81. /// <returns></returns>
  82. bool Add(TKey key, TValue value);
  83.  
  84. /// <summary>
  85. /// 添加或更新缓存
  86. /// </summary>
  87. /// <param name="key"></param>
  88. /// <param name="value"></param>
  89. /// <returns></returns>
  90. void AddOrUpdate(TKey key, TValue value);
  91.  
  92. /// <summary>
  93. /// 移除缓存
  94. /// </summary>
  95. /// <param name="key"></param>
  96. /// <param name="value"></param>
  97. /// <returns></returns>
  98. bool Remove(TKey key);
  99.  
  100. }
  101. }
  1. using System.Collections;
  2. using System.Collections.Generic;
  3. using System.Threading;
  4. using System.Threading.Tasks;
  5. using System.Linq;
  6.  
  7. namespace System
  8. {
  9.  
  10. internal class Cache<TKey, TValue> : ICache<TKey, TValue>
  11. {
  12. Dictionary<TKey, TValue> _map = new Dictionary<TKey, TValue>();
  13. ReaderWriterLockSlim _lock = new ReaderWriterLockSlim();
  14.  
  15. SemaphoreSlim _asyncLock;
  16.  
  17. SemaphoreSlim AsyncLock
  18. {
  19. get
  20. {
  21. if (_asyncLock == null)
  22. {
  23. _asyncLock = new SemaphoreSlim(, );
  24. }
  25. return _asyncLock;
  26. }
  27. }
  28.  
  29. public int Count
  30. {
  31. get
  32. {
  33. return _map.Count;
  34. }
  35. }
  36.  
  37. public IEnumerable<TKey> Keys
  38. {
  39. get
  40. {
  41. return _map.Keys;
  42. }
  43. }
  44.  
  45. #region Get
  46. public TValue Get(TKey key, Func<TValue> factory)
  47. {
  48. // Check cache
  49. _lock.EnterReadLock();
  50. TValue val;
  51. try
  52. {
  53. if (_map.TryGetValue(key, out val))
  54. return val;
  55. }
  56. finally
  57. {
  58. _lock.ExitReadLock();
  59. }
  60.  
  61. // Cache it
  62. _lock.EnterWriteLock();
  63. try
  64. {
  65. // Check again
  66. if (_map.TryGetValue(key, out val))
  67. return val;
  68.  
  69. // Create it
  70. val = factory();
  71.  
  72. // Store it
  73. _map.Add(key, val);
  74.  
  75. // Done
  76. return val;
  77. }
  78. finally
  79. {
  80. _lock.ExitWriteLock();
  81. }
  82. }
  83.  
  84. //public TValue Get(TKey key)
  85. //{
  86. // // Check cache
  87. // _lock.EnterReadLock();
  88. // TValue val;
  89. // try
  90. // {
  91. // _map.TryGetValue(key, out val);
  92. // return val;
  93. // }
  94. // finally
  95. // {
  96. // _lock.ExitReadLock();
  97. // }
  98. //}
  99.  
  100. public async Task<TValue> GetAsync(TKey key, Func<Task<TValue>> factory)
  101. {
  102. // Check cache
  103. //_lock.EnterReadLock();
  104. await AsyncLock.WaitAsync(-);
  105. TValue val;
  106. try
  107. {
  108. if (_map.TryGetValue(key, out val))
  109. return val;
  110. }
  111. finally
  112. {
  113. AsyncLock.Release();
  114. //_lock.ExitReadLock();
  115. }
  116.  
  117. // Cache it
  118. //_lock.EnterWriteLock();
  119. await AsyncLock.WaitAsync(-);
  120. try
  121. {
  122. // Check again
  123. if (_map.TryGetValue(key, out val))
  124. return val;
  125.  
  126. // Create it
  127. val = await factory();
  128.  
  129. // Store it
  130. _map.Add(key, val);
  131.  
  132. // Done
  133. return val;
  134. }
  135. finally
  136. {
  137. //_lock.ExitWriteLock();
  138. AsyncLock.Release();
  139. }
  140. }
  141.  
  142. //public async Task<TValue> GetAsync(TKey key)
  143. //{
  144. // // Check cache
  145. // //_lock.EnterReadLock();
  146. // await AsyncLock.WaitAsync(-1);
  147. // TValue val;
  148. // try
  149. // {
  150. // _map.TryGetValue(key, out val);
  151. // return val;
  152. // }
  153. // finally
  154. // {
  155. // AsyncLock.Release();
  156. // //_lock.ExitReadLock();
  157. // }
  158.  
  159. //}
  160.  
  161. #endregion
  162.  
  163. /// <summary>
  164. /// 获取数据,没有返回默认值
  165. /// </summary>
  166. /// <param name="index"></param>
  167. /// <returns></returns>
  168. public TValue this[TKey key]
  169. {
  170. get
  171. {
  172. _lock.EnterReadLock();
  173. TValue val;
  174. try
  175. {
  176. if (_map.TryGetValue(key, out val))
  177. return val;
  178. }
  179. finally
  180. {
  181. _lock.ExitReadLock();
  182. }
  183. return default(TValue);
  184. }
  185. set
  186. {
  187. AddOrUpdate(key, value);
  188. }
  189. }
  190.  
  191. public bool Update(TKey key, TValue value)
  192. {
  193. _lock.EnterReadLock();
  194. TValue val;
  195. try
  196. {
  197. if (!_map.TryGetValue(key, out val))
  198. return false;
  199. //val = value;
  200. _map[key] = value;
  201. return true;
  202. }
  203. finally
  204. {
  205. _lock.ExitReadLock();
  206. }
  207. }
  208.  
  209. public bool Add(TKey key, TValue value)
  210. {
  211. _lock.EnterReadLock();
  212. TValue val;
  213. try
  214. {
  215. if (_map.TryGetValue(key, out val))
  216. return false;
  217. _map.Add(key, value);
  218. return true;
  219. }
  220. finally
  221. {
  222. _lock.ExitReadLock();
  223. }
  224. }
  225.  
  226. public void AddOrUpdate(TKey key, TValue value)
  227. {
  228. _lock.EnterReadLock();
  229. TValue val;
  230. try
  231. {
  232. if (_map.TryGetValue(key, out val))
  233. // val = value;
  234. _map[key] = value;
  235. else
  236. _map.Add(key, value);
  237. }
  238. finally
  239. {
  240. _lock.ExitReadLock();
  241. }
  242.  
  243. }
  244.  
  245. public bool Remove(TKey key)
  246. {
  247. _lock.EnterReadLock();
  248. try
  249. {
  250. return _map.Remove(key);
  251. }
  252. finally
  253. {
  254. _lock.ExitReadLock();
  255. }
  256. }
  257.  
  258. public void Flush()
  259. {
  260. // Cache it
  261. _lock.EnterWriteLock();
  262. try
  263. {
  264. _map.Clear();
  265. }
  266. finally
  267. {
  268. _lock.ExitWriteLock();
  269. }
  270.  
  271. }
  272.  
  273. public bool ContainsKey(TKey key)
  274. {
  275. _lock.EnterReadLock();
  276. TValue val;
  277. try
  278. {
  279. if (_map.TryGetValue(key, out val))
  280. return true;
  281. return false;
  282. }
  283. finally
  284. {
  285. _lock.ExitReadLock();
  286. }
  287. }
  288.  
  289. public IEnumerator<KeyValuePair<TKey, TValue>> GetEnumerator()
  290. {
  291. return _map.GetEnumerator();
  292. }
  293.  
  294. IEnumerator IEnumerable.GetEnumerator()
  295. {
  296. return ((IEnumerable)_map).GetEnumerator();
  297. }
  298. }
  299. }
  1. using System;
  2. using System.Collections.Generic;
  3. using System.Linq;
  4. using System.Text;
  5. using System.Threading;
  6. using System.Threading.Tasks;
  7.  
  8. namespace System
  9. {
  10. /// <summary>
  11. /// 缓存工厂
  12. /// </summary>
  13. public static class CacheFactory
  14. {
  15.  
  16. internal static readonly List<Action> _actions;
  17.  
  18. internal static readonly Timer _timer;
  19.  
  20. static CacheFactory()
  21. {
  22. _expireTime = ;
  23. _actions = new List<Action>();
  24. _timer = new Timer(o =>
  25. {
  26. var actions = o as IEnumerable<Action>;
  27.  
  28. object lockObj = new object();
  29.  
  30. lock (lockObj)
  31. {
  32. foreach (var item in actions)
  33. {
  34. try
  35. {
  36. item();
  37. }
  38. catch
  39. {
  40. }
  41. }
  42. }
  43. }, _actions, Timeout.Infinite, Timeout.Infinite);
  44.  
  45. int time = * * _expireTime;
  46. _timer.Change(time, time);
  47. }
  48.  
  49. static int _expireTime;
  50. /// <summary>
  51. /// 获取或设置过期时间
  52. /// </summary>
  53. public static int ExpireTime
  54. {
  55. get { return _expireTime; }
  56. set
  57. {
  58. _expireTime = value;
  59. int time = * * _expireTime;
  60. _timer.Change(time, time);
  61. }
  62. }
  63.  
  64. /// <summary>
  65. /// 创建一个缓存
  66. /// </summary>
  67. /// <typeparam name="TKey"></typeparam>
  68. /// <typeparam name="TValue"></typeparam>
  69. /// <returns></returns>
  70. public static ICache<TKey, TValue> CreateCache<TKey, TValue>()
  71. {
  72. return new Cache<TKey, TValue>();
  73. //return ActivatorFactory.CreateInstance<ICache<TKey, TValue>>();
  74. }
  75.  
  76. /// <summary>
  77. /// 创建一个过期缓存
  78. /// </summary>
  79. /// <typeparam name="TKey"></typeparam>
  80. /// <typeparam name="TValue"></typeparam>
  81. /// <returns></returns>
  82. public static IExpireCache<TKey, TValue> CreateExpireCache<TKey, TValue>()
  83. {
  84. return new ExpireCache<TKey, TValue>();
  85. //return ActivatorFactory.CreateInstance<IExpireCache<TKey, TValue>>();
  86. }
  87.  
  88. /// <summary>
  89. /// 创建一个过期缓存
  90. /// </summary>
  91. /// <typeparam name="TKey"></typeparam>
  92. /// <typeparam name="TValue"></typeparam>
  93. /// <returns></returns>
  94. public static IExpireCache<TValue> CreateExpireCache<TValue>()
  95. {
  96. return new ExpireCache<TValue>();
  97. //return ActivatorFactory.CreateInstance<IExpireCache<TValue>>();
  98. }
  99.  
  100. }
  101. }

补充ICache的更多相关文章

  1. MVC Core 网站开发(Ninesky) 2.1、栏目的前台显示(补充)

    在2.1.栏目的前台显示中因右键没有添加视图把微软给鄙视了一下,后来有仔细研究了一下发现应该鄙视自己,其实这个功能是有的,是自己没搞清楚乱吐糟. 其实只要在NuGet中安装两个包(Microsoft. ...

  2. RabbitMq应用一的补充(RabbitMQ的应用场景)

    直接进入正题. 一.异步处理 场景:发送手机验证码,邮件 传统古老处理方式如下图 这个流程,全部在主线程完成,注册->入库->发送邮件->发送短信,由于都在主线程,所以要等待每一步完 ...

  3. Android Retrofit 2.0 使用-补充篇

    推荐阅读,猛戳: 1.Android MVP 实例 2.Android Retrofit 2.0使用 3.RxJava 4.RxBus 5.Android MVP+Retrofit+RxJava实践小 ...

  4. Android中使用ViewFlipper实现屏幕页面切换(关于坐标轴的问题已补充更改)

    屏幕切换指的是在同一个Activity内屏幕间的切换,ViewFlipper继承了Framelayout类,ViewAnimator类的作用是为FrameLayout里面的View切换提供动画效果.如 ...

  5. 关于《Linux.NET学习手记(8)》的补充说明

    早前的一两天<Linux.NET学习手记(8)>发布了,这一篇主要是讲述OWIN框架与OwinHost之间如何根据OWIN协议进行通信构成一套完整的系统.文中我们还直接学习如何直接操作OW ...

  6. Hexo的coney主题的一些补充说明

    title: Hexo的coney主题的一些补充说明 date: 2014-12-14 14:10:44 categories: Hexo tags: [hexo,技巧] --- Coney是一个非常 ...

  7. ASP.NET MVC5+EF6+EasyUI 后台管理系统(47)-工作流设计-补充

    系列目录 补充一下,有人要表单的代码,这个用代码生成器生成表Flow_Form表的Index代码就可以 加上几个按钮就可以了 <div class="mvctool"> ...

  8. 21-Python-Django进阶补充篇

    1. 路由部分补充 1.1 默认值 url: url(r'^index/', views.index, {'name': 'root'}), views: def index(request,name ...

  9. 像画笔一样慢慢画出Path的三种方法(补充第四种)

    今天大家在群里大家非常热闹的讨论像画笔一样慢慢画出Path的这种效果该如何实现. 北京-LGL 博客号@ligl007发起了这个话题.然后各路高手踊跃发表意见.最后雷叔 上海-雷蒙 博客号@雷蒙之星 ...

随机推荐

  1. UNITY 状态机 + SVN + 码云 下篇

    上篇说到自己写的一个FSM状态机,这篇写怎么把代码和码云联系在一起! 首先,我们应该知道为什么使用码云? 码云是开源中国社区2013年推出的基于 Git 的完全免费的代码托管服务,这个服务是基于 Gi ...

  2. Apache HTTP Server 2.2.26 发布

    Apache遗留产品线2.2.26发布.2013-11-13 之前的版本是2013-07-02的2.2.25 同样先在开发目录下放出下载,然后放到正式目录下.修正了大量的Bug.目前的稳定版2.4系列 ...

  3. hadoop+hive使用中遇到的问题汇总

    问题排查方式  一般的错误,查看错误输出,按照关键字google 异常错误(如namenode.datanode莫名其妙挂了):查看hadoop($HADOOP_HOME/logs)或hive日志 h ...

  4. Wireshark插件编写

    Wireshark插件编写 在抓包的过程中学习了使用wireshark,同时发现wireshark可以进行加载插件,便在网上学习了一下相应的插件开发技术. 需求编写一个私有协议名为SYC,使用UDP端 ...

  5. SQL提示介绍-强制并行

    查询提示一直是个很有争议的东西,因为他影响了sql server 自己选择执行计划.很多人在问是否应该使用查询提示的时候一般会被告知慎用或不要使用...但是个人认为善用提示在不修改语句的条件下,是常用 ...

  6. FusionCharts简单教程(二)-----使用js加载图像和setDataXML()加载数据

          前面一篇对FusionCharts进行了一个简单的介绍,而且建立了我们第一个图形,但是那个是在HTML中使用<OBJECT>和<EMBED>标记来加载图形的,但是这 ...

  7. js DOM优化相关探索

    我在这尝试两个方面:-->DOM与js -->DOM与浏览器 (最近在秒味视频上学到不少,哈哈哈) 一.DOM与js 1.js与dom的交互问题 频繁的与dom交互,是一件浪费时间与金钱的 ...

  8. [51单片机] 以从0开始做4位8段共阴数码管3461AS驱动谈细节决定高质量DIY

    目录 1)问题产生 2)失败尝试 3)最终方案 4)使用方法 5)知识共享 1)问题产生 在上一篇“以PWM控制直流电机为例建一个简单的51工程框架”中已向大家介绍了一个封装好的8位8段数码管的驱动( ...

  9. Visual Studio 2015速递(1)——C#6.0新特性怎么用

    系列文章 Visual Studio 2015速递(1)——C#6.0新特性怎么用 Visual Studio 2015速递(2)——提升效率和质量(VS2015核心竞争力) Visual Studi ...

  10. linux网络编程系列-网络连接的建立

    一个比较实用的连接函数,支持host为域名. #include <netdb.h> #include <sys/socket.h> #include <sys/types ...