C# 缓存的实现
阅读原文时间:2023年07月16日阅读:1

我们不是做第三方比如Redis等的缓存实现,而是根据实际情况,基于C#上做一些环境变量的保存,方便项目使用。

1、系统全局变量

很多时候,在系统运行开始,需要对系统的运行参数进行保存,以便供全局使用。

代码如下:

public class PFTCacheObject
{
///

/// 字典 ///
private static Dictionary _dataDic = new Dictionary();

    /// <summary>  
    /// 定义一个静态变量来保存类的实例  
    /// </summary>  
    private static PFTCacheObject \_session;

    /// <summary>  
    /// 定义一个标识确保线程同步  
    /// </summary>  
    private static readonly object \_locker = new object();

    /// <summary>  
    /// 单例  
    /// </summary>  
    /// <returns>返回类型为Session</returns>  
    public static PFTCacheObject Instance  
    {  
        get  
        {  
            if (\_session == null)  
            {  
                lock (\_locker)  
                {  
                    if (\_session == null)// 如果类的实例不存在则创建,否则直接返回  
                    {  
                        \_session = new PFTCacheObject();  
                    }  
                }  
            }  
            return \_session;  
        }  
    }

    #region Remove 移除

    /// <summary>  
    /// 删除成员  
    /// </summary>  
    /// <param name="name"></param>  
    public void Remove(string name)  
    {  
        \_dataDic.Remove(name);  
    }

    /// <summary>  
    /// 删除全部成员  
    /// </summary>  
    public void RemoveAll()  
    {  
        \_dataDic.Clear();  
    }  
    #endregion

    #region 本类的索引器

    /// <summary>  
    /// 本类的索引器  
    /// </summary>  
    /// <returns>返回Object成员</returns>  
    public Object this\[string index\]  
    {  
        get  
        {  
            if (\_dataDic.ContainsKey(index))  
            {  
                Object obj = (Object)\_dataDic\[index\];  
                return obj;  
            }  
            return null;  
        }  
        set  
        {  
            if (\_dataDic.ContainsKey(index))  
            {  
                \_dataDic.Remove(index);  
            }  
            \_dataDic.Add(index, value);  
        }  
    }  
    #endregion

}

这里使用一个静态变量的Dictionary来进行保存,所有项目均可以直接获取。

2、异步的数据缓存

在web上面,很多时候都是使用的HttpContext.Current.Items进行数据缓存,在.Net Framework框架上使用CallContext.LogicalSetData。在.Net Standard 上面CallContext.LogicalSetData已经不能使用了,替换他的方法是AsyncLocal。因为我们现在都是使用的是.Net Standard,并且我们项目并不仅仅是web,所以这里我们就只用使用AsyncLocal实现。

代码如下

public class PFTCallContext
{

    #region  共享数据库连接

    private static AsyncLocal<object> \_asyncLocalConnectionOject = new AsyncLocal<object>();

    /// <summary>  
    /// 设置共享数据库连接  
    /// </summary>  
    /// <param name="obj"></param>  
    public static void SetConnectionOject(object obj)  
    {  
        \_asyncLocalConnectionOject.Value = obj;  
    }

    /// <summary>  
    /// 获取共享数据库连接  
    /// </summary>  
    /// <returns></returns>  
    public static object GetConnectionOject()  
    {  
        return \_asyncLocalConnectionOject.Value;  
    }

    /// <summary>  
    /// 清空共享数据库连接  
    /// </summary>  
    public static void ClearConnectionOject()  
    {  
        \_asyncLocalConnectionOject.Value = null;  
    }

    #endregion

}

这里我们就先定义一个当前数据库连接对象的缓存。如果还需要其他的定义,你可以直接实现。

3、.Net Core 的MemoryCache

本来这块想使用.Net Framework框架中的cache的,但是.Net Core才是未来的大势,而且.Net Framework的cache已经有很多的实现方法了,所以这里我就直接用.Net Core 的MemoryCache。.Net Core蜗牛也在学习中,相关的API也在不断的研究,如果有问题,请大家帮忙纠正。

public static class PFTCache
{
public readonly static IMemoryCache _memoryCache;

    static PFTCache()  
    {  
        \_memoryCache = new MemoryCache(Options.Create(new MemoryCacheOptions()));  
    }

    #region 常规缓存  
    /// <summary>  
    /// 获取缓存的值  
    /// </summary>  
    /// <param name="key"></param>  
    /// <returns></returns>  
    public static Object GetCache(string key)  
    {  
        return \_memoryCache.Get(key);  
    }  
    /// <summary>  
    /// 移除缓存  
    /// </summary>  
    /// <param name="key"></param>  
    public static void Remove(string key)  
    {  
        \_memoryCache.Remove(key);  
    }  
    /// <summary>  
    /// 设置缓存  
    /// </summary>  
    /// <param name="key"></param>  
    /// <param name="value"></param>  
    public static void SetCache(string key, Object value)  
    {  
        \_memoryCache.GetOrCreate(key, entry =>  
        {  
            return value;  
        });  
    }  
    /// <summary>  
    /// 设置缓存(固定时间过期)  
    /// </summary>  
    /// <param name="key"></param>  
    /// <param name="value"></param>  
    /// <param name="absoluteExpiration"></param>  
    public static void SetCacheAbsolute(string key, Object value, int absoluteExpiration)  
    {  
        \_memoryCache.GetOrCreate(key, entry =>  
        {

            entry.SetAbsoluteExpiration(TimeSpan.FromSeconds(absoluteExpiration));  
            return value;  
        });  
    }  
    /// <summary>  
    /// 设置缓存(滚动时间过期)  
    /// </summary>  
    /// <param name="key"></param>  
    /// <param name="value"></param>  
    /// <param name="slidingExpiration"></param>  
    public static void SetCacheSliding(string key, Object value, int slidingExpiration)  
    {  
        \_memoryCache.GetOrCreate(key, entry =>  
        {

            entry.SetSlidingExpiration(TimeSpan.FromSeconds(slidingExpiration));  
            return value;  
        });  
    }

    #endregion

    #region 文件依赖缓存  
    /// <summary>  
    /// 文件依赖缓存  
    /// </summary>  
    /// <param name="key"></param>  
    /// <param name="fullName"></param>  
    /// <returns></returns>  
    public static string DependentCacheFile(string key, string fullName)  
    {  
        var basePath = PFTFile.GetDirectoryName(fullName);  
        var fileName = PFTFile.GetFileName(fullName);  
        var fileProvider = new PhysicalFileProvider(basePath);  
        return \_memoryCache.GetOrCreate(key, entry =>  
        {  
            entry.AddExpirationToken(fileProvider.Watch(fileName));  
            return PFTFile.IsExistFile(fullName) ? PFTFile.ReadFile(fullName) : string.Empty;  
        });  
    }  
    #endregion

}

好了,关于缓存这块蜗牛就先说到这里。