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>>();
}
}
}