补充ICache
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的更多相关文章
- MVC Core 网站开发(Ninesky) 2.1、栏目的前台显示(补充)
在2.1.栏目的前台显示中因右键没有添加视图把微软给鄙视了一下,后来有仔细研究了一下发现应该鄙视自己,其实这个功能是有的,是自己没搞清楚乱吐糟. 其实只要在NuGet中安装两个包(Microsoft. ...
- RabbitMq应用一的补充(RabbitMQ的应用场景)
直接进入正题. 一.异步处理 场景:发送手机验证码,邮件 传统古老处理方式如下图 这个流程,全部在主线程完成,注册->入库->发送邮件->发送短信,由于都在主线程,所以要等待每一步完 ...
- Android Retrofit 2.0 使用-补充篇
推荐阅读,猛戳: 1.Android MVP 实例 2.Android Retrofit 2.0使用 3.RxJava 4.RxBus 5.Android MVP+Retrofit+RxJava实践小 ...
- Android中使用ViewFlipper实现屏幕页面切换(关于坐标轴的问题已补充更改)
屏幕切换指的是在同一个Activity内屏幕间的切换,ViewFlipper继承了Framelayout类,ViewAnimator类的作用是为FrameLayout里面的View切换提供动画效果.如 ...
- 关于《Linux.NET学习手记(8)》的补充说明
早前的一两天<Linux.NET学习手记(8)>发布了,这一篇主要是讲述OWIN框架与OwinHost之间如何根据OWIN协议进行通信构成一套完整的系统.文中我们还直接学习如何直接操作OW ...
- Hexo的coney主题的一些补充说明
title: Hexo的coney主题的一些补充说明 date: 2014-12-14 14:10:44 categories: Hexo tags: [hexo,技巧] --- Coney是一个非常 ...
- ASP.NET MVC5+EF6+EasyUI 后台管理系统(47)-工作流设计-补充
系列目录 补充一下,有人要表单的代码,这个用代码生成器生成表Flow_Form表的Index代码就可以 加上几个按钮就可以了 <div class="mvctool"> ...
- 21-Python-Django进阶补充篇
1. 路由部分补充 1.1 默认值 url: url(r'^index/', views.index, {'name': 'root'}), views: def index(request,name ...
- 像画笔一样慢慢画出Path的三种方法(补充第四种)
今天大家在群里大家非常热闹的讨论像画笔一样慢慢画出Path的这种效果该如何实现. 北京-LGL 博客号@ligl007发起了这个话题.然后各路高手踊跃发表意见.最后雷叔 上海-雷蒙 博客号@雷蒙之星 ...
随机推荐
- ASP.NET MVC3 Razor 初心者容易遇到的問題(转)
这是一些相关的文章地址 http://demo.tc/Post/679 http://blog.csdn.net/cheny_com/article/details/6298496
- .NET跨平台实践:用C#开发Linux守护进程
Linux守护进程(Daemon)是Linux的后台服务进程,它脱离了与控制终端的关联,直接由Linux init进程管理其生命周期,即使你关闭了控制台,daemon也能在后台正常工作. 一句话,为L ...
- [Openwrt 项目开发笔记]:Openwrt平台搭建(一)
[Openwrt项目开发笔记]系列文章传送门:http://www.cnblogs.com/double-win/p/3888399.html 正文: 最近开始着手进行Openwrt平台的物联网网关设 ...
- 初中级Javascript程序员必修学习目录
很多人总感觉javascript无法入门,笔者在这里写一下自己的学习过程,以及个人认为的最佳看书过程,只要各位能按照本人所说步骤走下去,不用很长时间,坚持个3个月,你的js层级会提高一个档次,无他,唯 ...
- Ng Http Request/response格式转换
angular作为Single Page Application推荐的交互方式当然是基于json的ajax调用.但今天要说的是当你不幸工作在一个遗留或者不可控制的服务上,而这服务是基于非json提交方 ...
- [安卓] 19、一个蓝牙4.0安卓DEMO
一.工程结构&概述 整个应用包含两个按钮,一个是搜索所有蓝牙设备,另一个是连接所有蓝牙设备~ 下面是整个工程的文件结构: 二.代码业务流程跟踪 2.1.两个按钮 下面讲讲该工程里的主要跳转流程 ...
- 学习Scala02 基本类型
scala中有9大基本类型: Byte .Short .Int .Long. Char .String .Float. Double .Boolean 与java的基本类型看起来基本是一致的,但实际上 ...
- jQuery.fn.extend(object) object中this的指向
看到下面的代码后,一下子懵逼了.这个this指向哪儿去了. jQuery.fn.extend({ check: function() { return this.each(function() { t ...
- Java mac 上编写Java代码
看视频学JAVA,不想下载 notepad++之类的,虽然知道mac有内嵌的JAVA sdk ,但是还是不知道怎么编写,今天终于编写了我的第一个JAVA程序,还是以 Hello World 开始吧 1 ...
- 爱上MVC3系列~开发一个站点地图(俗称面包屑)
回到目录 原来早在webform控件时代就有了SiteMap这个东西,而进行MVC时代后,我们也希望有这样一个东西,它为我们提供了不少方便,如很方便的实现页面导航的内容修改,页面导航的样式换肤等. 我 ...