緩存處理類(MemoryCache結合文件緩存)


想提升站點的性能,於是增加了緩存,但是站點不會太大,於是不會到分布式memcached的緩存和redis這個nosql庫,於是自己封裝了.NET內置的緩存組件

原先使用System.Web.Caching.Cache,但是asp.net會在System.Web.Caching.Cache緩存頁面等數據,於是替換了System.Web.Caching.Cache為MemoryCache。

而在使用MemoryCache的時候,重新啟動網站會丟失緩存,於是加了自己的擴展,將緩存序列化存放在文件內,在緩存丟的時候從文件內獲取緩存,做了簡易的擴展。(現在應用在我的Cactus里面)

using System;
using System.Collections;
using System.Web;
using System.Text;
using System.IO;
using System.Runtime.Caching;
using System.Diagnostics;
using System.Runtime.Serialization.Formatters.Binary;
using System.Configuration;
using System.Collections.Generic;

namespace Cactus.Common
{
    /// <summary>
    /// 緩存對象數據結構
    /// </summary>
    [Serializable()]
    public class CacheData{
        public object Value { get;set;}
        public DateTime CreateTime { get; set; }
        public DateTimeOffset AbsoluteExpiration { get; set; }
        public DateTime FailureTime { get 
        { if (AbsoluteExpiration == System.Runtime.Caching.ObjectCache.InfiniteAbsoluteExpiration) 
            {
                return AbsoluteExpiration.DateTime;
            } 
            else { return CreateTime.AddTicks(AbsoluteExpiration.Ticks); } } 
        }
        public CacheItemPriority Priority { get; set; }
    }
    
    /// <summary>
    /// 緩存處理類(MemoryCache)
    /// </summary>
    public class CacheHelper
    {
        //在應用程序的同級目錄(主要防止外部訪問)
        public static string filePath = Path.GetFullPath(AppDomain.CurrentDomain.BaseDirectory + ConfigurationManager.ConnectionStrings["filecache"].ConnectionString);
        //文件擴展名
        public static string fileExt = ".cache";
        /// <summary>
        /// 獲取數據緩存
        /// </summary>
        /// <param name="cacheKey"></param>
        public static object GetCache(string cacheKey)
        {
            //System.Web.Caching.Cache objCache = HttpRuntime.Cache;
            //return objCache[cacheKey];
            long i=System.Runtime.Caching.MemoryCache.Default.GetCount();
            CacheItem objCache=System.Runtime.Caching.MemoryCache.Default.GetCacheItem(cacheKey);
            if (objCache == null)
            {
                string _filepath = filePath + cacheKey + fileExt;
                if (File.Exists(_filepath))
                {
                    FileStream _file = File.OpenRead(_filepath);
                    if (_file.CanRead)
                    {
                        Debug.WriteLine("緩存反序列化獲取數據:" + cacheKey);
                        object obj = CacheHelper.BinaryDeSerialize(_file);
                        CacheData _data = (CacheData)obj;
                        if (_data != null)
                        {
                            //判斷是否過期
                            if (_data.FailureTime >= DateTime.Now)
                            {
                                //將數據添加到內存
                                CacheHelper.SetCacheToMemory(cacheKey, _data);
                                return _data.Value;
                            }
                            else
                            {
                                Debug.WriteLine("數據過期:" + cacheKey);
                                File.Delete(_filepath);
                                //數據過期
                                return null;
                            }
                        }
                        else { return null; }
                    }
                    else { return null; }
                }
                else { return null; }
            }
            else {
                CacheData _data = (CacheData)objCache.Value;
                return _data.Value;
            }
        }
        /// <summary>
        /// 內存緩存數
        /// </summary>
        /// <returns></returns>
        public static object GetCacheCount()
        {
            return System.Runtime.Caching.MemoryCache.Default.GetCount();
        }
        /// <summary>
        /// 文件緩存數
        /// </summary>
        /// <returns></returns>
        public static object GetFileCacheCount()
        {
            DirectoryInfo di = new DirectoryInfo(filePath);
            return di.GetFiles().Length;
        }
                
        /// <summary>
        /// 設置數據緩存
        /// </summary>
        public static bool SetCache(string cacheKey, object objObject, CacheItemPolicy policy)
        {
            //System.Web.Caching.Cache objCache = HttpRuntime.Cache;            
            //objCache.Insert(cacheKey, objObject);
            string _filepath = filePath + cacheKey + fileExt;
            if (Directory.Exists(filePath)==false) {
                Directory.CreateDirectory(filePath);
            }
            //設置緩存數據的相關參數
            CacheData data = new CacheData() { Value = objObject, CreateTime = DateTime.Now, AbsoluteExpiration = policy.AbsoluteExpiration, Priority = policy.Priority };
            CacheItem objCache = new CacheItem(cacheKey, data);
            FileStream stream = null;
            if (File.Exists(_filepath) == false)
            {
                stream = new FileStream(_filepath, FileMode.CreateNew, FileAccess.Write, FileShare.Write);
            }
            else {
                stream = new FileStream(_filepath, FileMode.Create, FileAccess.Write, FileShare.Write);
            }
            Debug.WriteLine("緩存序列化設置數據:" + cacheKey);
            CacheHelper.BinarySerialize(stream, data);
            return System.Runtime.Caching.MemoryCache.Default.Add(objCache, policy);
        }
        public static bool SetCacheToMemory(string cacheKey, CacheData data)
        {
            CacheItemPolicy policy = new CacheItemPolicy();
            CacheItem objCache = new CacheItem(cacheKey, data);
            policy.AbsoluteExpiration = data.AbsoluteExpiration;
            policy.Priority = CacheItemPriority.NotRemovable;
            return System.Runtime.Caching.MemoryCache.Default.Add(objCache, policy);
        }

        public static bool SetCache(string cacheKey, object objObject, DateTimeOffset AbsoluteExpiration)
        {
            //System.Web.Caching.Cache objCache = HttpRuntime.Cache;            
            //objCache.Insert(cacheKey, objObject);
            CacheItemPolicy _priority = new CacheItemPolicy();
            _priority.Priority = CacheItemPriority.NotRemovable;
            _priority.AbsoluteExpiration = AbsoluteExpiration;
            return SetCache(cacheKey, objObject, _priority);
        }

        public static bool SetCache(string cacheKey, object objObject, CacheItemPriority priority)
        {
            //System.Web.Caching.Cache objCache = HttpRuntime.Cache;            
            //objCache.Insert(cacheKey, objObject);
            CacheItemPolicy _priority = new CacheItemPolicy();
            _priority.Priority = priority;
            _priority.AbsoluteExpiration = System.Runtime.Caching.ObjectCache.InfiniteAbsoluteExpiration;
            return SetCache(cacheKey, objObject, _priority);
        }
        /// <summary>
        /// 設置數據緩存
        /// </summary>
        public static bool SetCache(string cacheKey, object objObject)
        {
            //System.Web.Caching.Cache objCache = HttpRuntime.Cache;
            //objCache.Insert(cacheKey, objObject, null, DateTime.MaxValue, timeout, System.Web.Caching.CacheItemPriority.NotRemovable, null);
            return CacheHelper.SetCache(cacheKey, objObject, System.Runtime.Caching.CacheItemPriority.NotRemovable);
        }

        /// <summary>
        /// 移除指定數據緩存
        /// </summary>
        public static void RemoveCache(string cacheKey)
        {
            //System.Web.Caching.Cache cache = HttpRuntime.Cache;
            //cache.Remove(cacheKey);
            System.Runtime.Caching.MemoryCache.Default.Remove(cacheKey);
            string _filepath = filePath + cacheKey + fileExt;
            File.Delete(_filepath);
        }

        /// <summary>
        /// 移除全部緩存
        /// </summary>
        public static void RemoveAllCache()
        {
            //System.Web.Caching.Cache cache = HttpRuntime.Cache;
            //IDictionaryEnumerator cacheEnum = cache.GetEnumerator();
            //while (cacheEnum.MoveNext())
            //{
            //    cache.Remove(cacheEnum.Key.ToString());
            //}
            MemoryCache _cache = System.Runtime.Caching.MemoryCache.Default;
            foreach (var _c in _cache.GetValues(null))
            {
                _cache.Remove(_c.Key);
            }
            DirectoryInfo di = new DirectoryInfo(filePath);
            di.Delete(true);
        }
        /// <summary>
        /// 清除指定緩存
        /// </summary>
        /// <param name="type">1:內存 2:文件</param>
        public static void RemoveAllCache(int type)
        {
            if (type == 1) 
            {
                MemoryCache _cache = System.Runtime.Caching.MemoryCache.Default;
                foreach (var _c in _cache.GetValues(null))
                {
                    _cache.Remove(_c.Key);
                }
            } 
            else if (type == 2)
            {
                DirectoryInfo di = new DirectoryInfo(filePath);
                di.Delete(true);
            } 
        }

        #region 流序列化
        public static void BinarySerialize(Stream stream, object obj)
        {
            try
            {
                stream.Seek(0, SeekOrigin.Begin);
                BinaryFormatter formatter = new BinaryFormatter();
                formatter.Serialize(stream, obj);
            }
            catch (Exception e)
            {
                IOHelper.WriteDebug(e);
            }
            finally
            {
                //stream.Close();
                stream.Dispose();
            }
        }

        public static object BinaryDeSerialize(Stream stream)
        {
            object obj = null;
            stream.Seek(0, SeekOrigin.Begin);
            try
            {
                BinaryFormatter formatter = new BinaryFormatter();
                obj = formatter.Deserialize(stream);
            }
            catch (Exception e)
            {
                IOHelper.WriteDebug(e);
            }
            finally
            {
                //stream.Close();
                stream.Dispose();
            }
            return obj;
        }
        #endregion
    }
}

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM