using System;
using System.Collections.Generic;
using System.Threading.Tasks;
namespace System
{ /// <summary>
/// 一个接口,表示缓存
/// </summary>
/// <typeparam name="TKey"></typeparam>
/// <typeparam name="TValue"></typeparam>
public interface ICache<TKey, TValue> : IEnumerable<KeyValuePair<TKey, TValue>>
{
/// <summary>
/// 获取当前缓存的数量
/// </summary>
int Count { get; } IEnumerable<TKey> Keys { get; } /// <summary>
/// 是否包含键
/// </summary>
bool ContainsKey(TKey key); /// <summary>
/// 查询缓存
/// </summary>
/// <param name="key"></param>
/// <param name="factory"></param>
/// <returns></returns>
TValue Get(TKey key, Func<TValue> factory); ///// <summary>
///// 查询缓存
///// </summary>
///// <param name="key"></param>
///// <returns></returns>
//TValue Get(TKey key); /// <summary>
/// 查询缓存
/// </summary>
/// <param name="key"></param>
/// <param name="factory"></param>
/// <returns></returns>
Task<TValue> GetAsync(TKey key, Func<Task<TValue>> factory); ///// <summary>
///// 查询缓存
///// </summary>
///// <param name="key"></param>
///// <returns></returns>
//Task<TValue> GetAsync(TKey key); /// <summary>
/// 获取数据,没有返回默认值
/// </summary>
/// <param name="index"></param>
/// <returns></returns>
TValue this[TKey key] { get; set; } /// <summary>
/// 清空缓存
/// </summary>
void Flush(); /// <summary>
/// 更新缓存
/// </summary>
/// <param name="key"></param>
/// <param name="value"></param>
/// <returns></returns>
bool Update(TKey key, TValue value); /// <summary>
/// 添加缓存
/// </summary>
/// <param name="key"></param>
/// <param name="value"></param>
/// <returns></returns>
bool Add(TKey key, TValue value); /// <summary>
/// 添加或更新缓存
/// </summary>
/// <param name="key"></param>
/// <param name="value"></param>
/// <returns></returns>
void AddOrUpdate(TKey key, TValue value); /// <summary>
/// 移除缓存
/// </summary>
/// <param name="key"></param>
/// <param name="value"></param>
/// <returns></returns>
bool Remove(TKey key); }
}
using System.Collections;
using System.Collections.Generic;
using System.Threading;
using System.Threading.Tasks;
using System.Linq; namespace System
{ internal class Cache<TKey, TValue> : ICache<TKey, TValue>
{
Dictionary<TKey, TValue> _map = new Dictionary<TKey, TValue>();
ReaderWriterLockSlim _lock = new ReaderWriterLockSlim(); SemaphoreSlim _asyncLock; SemaphoreSlim AsyncLock
{
get
{
if (_asyncLock == null)
{
_asyncLock = new SemaphoreSlim(, );
}
return _asyncLock;
}
} public int Count
{
get
{
return _map.Count;
}
} public IEnumerable<TKey> Keys
{
get
{
return _map.Keys;
}
} #region Get
public TValue Get(TKey key, Func<TValue> factory)
{
// Check cache
_lock.EnterReadLock();
TValue val;
try
{
if (_map.TryGetValue(key, out val))
return val;
}
finally
{
_lock.ExitReadLock();
} // Cache it
_lock.EnterWriteLock();
try
{
// Check again
if (_map.TryGetValue(key, out val))
return val; // Create it
val = factory(); // Store it
_map.Add(key, val); // Done
return val;
}
finally
{
_lock.ExitWriteLock();
}
} //public TValue Get(TKey key)
//{
// // Check cache
// _lock.EnterReadLock();
// TValue val;
// try
// {
// _map.TryGetValue(key, out val);
// return val;
// }
// finally
// {
// _lock.ExitReadLock();
// }
//} public async Task<TValue> GetAsync(TKey key, Func<Task<TValue>> factory)
{
// Check cache
//_lock.EnterReadLock();
await AsyncLock.WaitAsync(-);
TValue val;
try
{
if (_map.TryGetValue(key, out val))
return val;
}
finally
{
AsyncLock.Release();
//_lock.ExitReadLock();
} // Cache it
//_lock.EnterWriteLock();
await AsyncLock.WaitAsync(-);
try
{
// Check again
if (_map.TryGetValue(key, out val))
return val; // Create it
val = await factory(); // Store it
_map.Add(key, val); // Done
return val;
}
finally
{
//_lock.ExitWriteLock();
AsyncLock.Release();
}
} //public async Task<TValue> GetAsync(TKey key)
//{
// // Check cache
// //_lock.EnterReadLock();
// await AsyncLock.WaitAsync(-1);
// TValue val;
// try
// {
// _map.TryGetValue(key, out val);
// return val;
// }
// finally
// {
// AsyncLock.Release();
// //_lock.ExitReadLock();
// } //} #endregion /// <summary>
/// 获取数据,没有返回默认值
/// </summary>
/// <param name="index"></param>
/// <returns></returns>
public TValue this[TKey key]
{
get
{
_lock.EnterReadLock();
TValue val;
try
{
if (_map.TryGetValue(key, out val))
return val;
}
finally
{
_lock.ExitReadLock();
}
return default(TValue);
}
set
{
AddOrUpdate(key, value);
}
} public bool Update(TKey key, TValue value)
{
_lock.EnterReadLock();
TValue val;
try
{
if (!_map.TryGetValue(key, out val))
return false;
//val = value;
_map[key] = value;
return true;
}
finally
{
_lock.ExitReadLock();
}
} public bool Add(TKey key, TValue value)
{
_lock.EnterReadLock();
TValue val;
try
{
if (_map.TryGetValue(key, out val))
return false;
_map.Add(key, value);
return true;
}
finally
{
_lock.ExitReadLock();
}
} public void AddOrUpdate(TKey key, TValue value)
{
_lock.EnterReadLock();
TValue val;
try
{
if (_map.TryGetValue(key, out val))
// val = value;
_map[key] = value;
else
_map.Add(key, value);
}
finally
{
_lock.ExitReadLock();
} } public bool Remove(TKey key)
{
_lock.EnterReadLock();
try
{
return _map.Remove(key);
}
finally
{
_lock.ExitReadLock();
}
} public void Flush()
{
// Cache it
_lock.EnterWriteLock();
try
{
_map.Clear();
}
finally
{
_lock.ExitWriteLock();
} } public bool ContainsKey(TKey key)
{
_lock.EnterReadLock();
TValue val;
try
{
if (_map.TryGetValue(key, out val))
return true;
return false;
}
finally
{
_lock.ExitReadLock();
}
} public IEnumerator<KeyValuePair<TKey, TValue>> GetEnumerator()
{
return _map.GetEnumerator();
} IEnumerator IEnumerable.GetEnumerator()
{
return ((IEnumerable)_map).GetEnumerator();
}
}
}
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks; namespace System
{
/// <summary>
/// 缓存工厂
/// </summary>
public static class CacheFactory
{ internal static readonly List<Action> _actions; internal static readonly Timer _timer; static CacheFactory()
{
_expireTime = ;
_actions = new List<Action>();
_timer = new Timer(o =>
{
var actions = o as IEnumerable<Action>; object lockObj = new object(); lock (lockObj)
{
foreach (var item in actions)
{
try
{
item();
}
catch
{
}
}
}
}, _actions, Timeout.Infinite, Timeout.Infinite); int time = * * _expireTime;
_timer.Change(time, time);
} static int _expireTime;
/// <summary>
/// 获取或设置过期时间
/// </summary>
public static int ExpireTime
{
get { return _expireTime; }
set
{
_expireTime = value;
int time = * * _expireTime;
_timer.Change(time, time);
}
} /// <summary>
/// 创建一个缓存
/// </summary>
/// <typeparam name="TKey"></typeparam>
/// <typeparam name="TValue"></typeparam>
/// <returns></returns>
public static ICache<TKey, TValue> CreateCache<TKey, TValue>()
{
return new Cache<TKey, TValue>();
//return ActivatorFactory.CreateInstance<ICache<TKey, TValue>>();
} /// <summary>
/// 创建一个过期缓存
/// </summary>
/// <typeparam name="TKey"></typeparam>
/// <typeparam name="TValue"></typeparam>
/// <returns></returns>
public static IExpireCache<TKey, TValue> CreateExpireCache<TKey, TValue>()
{
return new ExpireCache<TKey, TValue>();
//return ActivatorFactory.CreateInstance<IExpireCache<TKey, TValue>>();
} /// <summary>
/// 创建一个过期缓存
/// </summary>
/// <typeparam name="TKey"></typeparam>
/// <typeparam name="TValue"></typeparam>
/// <returns></returns>
public static IExpireCache<TValue> CreateExpireCache<TValue>()
{
return new ExpireCache<TValue>();
//return ActivatorFactory.CreateInstance<IExpireCache<TValue>>();
} }
}

补充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. SQLSERVER 里SELECT COUNT(1) 和SELECT COUNT(*)哪个性能好?

    SQLSERVER 里SELECT COUNT(1) 和SELECT COUNT(*)哪个性能好? 今天遇到某人在我以前写的一篇文章里问到 如果统计信息没来得及更新的话,那岂不是统计出来的数据时错误的 ...

  2. dojo/dom-class源码学习

    dom-class模块是dojo中对于一个元素class特性的操作(特性与属性的区别),主要方法有: contains 判断元素是否包含某个css class add 为元素添加某个css class ...

  3. Flume概述和简单实例

    Flume概述 Flume是一个分布式.可靠.和高可用的海量日志采集.聚合和传输的系统.支持在日志系统中定制各类数据发送方,用于收集数据;同时,Flume提供对数据进行简单处理,并写到各种数据接受方( ...

  4. Ubuntu环境搭建系列—WPS/LAMP/Python篇

    由于篇幅不宜太长,所以就将此文分成了两部分,在第一部分中我们讲解了google-chrome(谷歌浏览器)的安装,jdk的环境配置,android开发的环境搭建.那么在第二部分中,位们将讲解的是金山W ...

  5. 在github上写个人简历——最简单却又不容易的内容罗列

    前篇博客分享了一下自己初入github的过程,傻瓜式一步步搭建好主页后,终于该做正事儿了——写简历.在脑袋中构思了很多版本,最后终于决定,先写一个最传统的版本,于是我在箱子中翻出我word版本的简历, ...

  6. querySelector和querySelectorAll

    jQuery被开发者如此的青睐和它强大的选择器有很大关系,比起笨重的document.getElementById.document.getElementByName… ,查找元素很方便,其实W3C中 ...

  7. NoSQL和Redis简介及Redis在Windows下的安装和使用教程

    转载于:http://www.itxuexiwang.com/a/shujukujishu/redis/2016/0216/103.html?1455869099 NoSQL简介 介绍redis前,我 ...

  8. JS之BOM

    ECMAScript 是 JavaScript 的核心,但如果要在 Web 中使用 JavaScript,那么 BOM(浏览器对象模型)则无疑才是真正的核心.BOM 提供了很多对象,用于访问浏览器的功 ...

  9. salesforce 零基础学习(三十八)Translate 的使用(国际化处理)

    本篇参考:http://resources.docs.salesforce.com/200/17/en-us/sfdc/pdf/salesforce_workbench_cheatsheet.pdf ...

  10. Win7系统.net framework 4.0没有注册导致部署在IIS的站点跑不起来怎么办

    win7装了VS再装IIS,结果IIS里面有.NET4.0,但是程序始终是跑不起来,怎么办呢? 分析觉得可能是因为4.0没有注册到IIS,在win7下如果先安装vs2010 (附带会安装Microso ...