首页 > 代码库 > 【C#】缓存数据

【C#】缓存数据

namespace WpfCopy.Controls{    public class CacheFileEventArgs : EventArgs    {        public bool IsFaulted { get; private set; }        public CacheFileModel CacheFile { get; private set; }        public CacheFileEventArgs(CacheFileModel cacheFile)        {            CacheFile = cacheFile;            IsFaulted = false;        }        public CacheFileEventArgs()        {            IsFaulted = true;        }    }    public class CacheFileModel    {        public string RemoteFile { get; set; }        public string LocalFile { get; set; }        public DateTime CreateTime { get; set; }        public DateTime LastUseTime { get; set; }    }    class FileCacheMgr    {        private const string CacheDir = "CacheFile";        private const string CacheDataFile = "file.cache";        /// <summary>        /// 缓存数据文件的读写锁        /// </summary>        readonly object _cacheDataFileLock = new object();        /// <summary>        /// 管理缓存数据的锁        /// </summary>        readonly object _cacheLock = new object();        /// <summary>        /// 缓存数据任务的锁        /// </summary>        readonly object _cacheTaskLock = new object();        /// <summary>        /// 缓存数据字典        /// </summary>        Dictionary<string, CacheFileModel> _cacheDict = new Dictionary<string, CacheFileModel>();        /// <summary>        /// 下载任务字典        /// </summary>        readonly Dictionary<string, WeakDelegateCollection<CacheFileEventArgs>> _cacheTaskDict = new Dictionary<string, WeakDelegateCollection<CacheFileEventArgs>>();        private static readonly FileCacheMgr instance = new FileCacheMgr();        public static FileCacheMgr Instance { get { return instance; } }        public FileCacheMgr()        {        }        /// <summary>        /// 读取缓存        /// </summary>        void LoadCacheData()        {            lock (_cacheDataFileLock)            {                if (!File.Exists(CacheDataFile) && Directory.Exists(CacheDir))                    Directory.Delete(CacheDir, true);                var xs = new XmlSerializer(typeof(List<CacheFileModel>));                using (Stream stream = new FileStream(CacheDataFile, FileMode.Open, FileAccess.Read))                {                    var list = xs.Deserialize(stream) as List<CacheFileModel> ?? new List<CacheFileModel>();                    _cacheDict = list.ToDictionary(m => m.RemoteFile);                }            }        }        /// <summary>        /// 保存缓存        /// </summary>        void SaveCacheData()        {            lock (_cacheDataFileLock)            {                try                {                    var xs = new XmlSerializer(typeof(List<CacheFileModel>));                    using (Stream stream = new FileStream(CacheDataFile, FileMode.Create, FileAccess.Write))                    {                        xs.Serialize(stream, _cacheDict.Values.ToList<CacheFileModel>());                    }                }                catch (Exception)                {                    File.Delete(CacheDataFile);                }            }        }        /// <summary>        /// 清除过期缓存        /// </summary>        public void ClearExpireCache()        {            try            {                List<string> clearList = new List<string>();                foreach (var item in _cacheDict)                {                    if (DateTime.Now - item.Value.LastUseTime > TimeSpan.FromDays(7))                        clearList.Add(item.Key);                }                foreach (var item in clearList)                {                    File.Delete(_cacheDict[item].LocalFile);                    _cacheDict.Remove(item);                }                SaveCacheData();            }            catch (Exception ex)            {                throw ex;            }        }        /// <summary>        /// 添加缓存数据        /// </summary>        /// <param name="model"></param>        public void AddCacheData(CacheFileModel model)        {            if (model == null)                throw new ArgumentException("model");            lock (_cacheLock)            {                if (_cacheDict.ContainsKey(model.RemoteFile) == false)                {                    _cacheDict.Add(model.RemoteFile, model);                    SaveCacheData();                }            }        }        /// <summary>        /// 删除缓存文件--        /// </summary>        /// <param name="model"></param>        public void RemoveCacheData(CacheFileModel model)        {            if (model == null)                throw new ArgumentException("model");            if (File.Exists(model.LocalFile))                File.Delete(model.LocalFile);            if (_cacheDict.ContainsKey(model.RemoteFile))            {                _cacheDict.Remove(model.RemoteFile);                SaveCacheData();            }        }        /// <summary>        /// 获取缓存数据,如果不存在,则创建下载任务        /// </summary>        /// <param name="remoteFile"></param>        /// <param name="callback"></param>        /// <param name="getFtpFunc"></param>        void GetCacheFile(string remoteFile, EventHandler<CacheFileEventArgs> callback, Func<MyFtp> getFtpFunc)        {            if (_cacheDict.ContainsKey(remoteFile))            {                CacheFileModel cache = _cacheDict[remoteFile];                if (File.Exists(cache.LocalFile))                {                    cache.LastUseTime = DateTime.Now;                    SaveCacheData();                    if (callback != null)                    {                        callback(this, new CacheFileEventArgs(cache));                    }                    return;                }                else                {                    _cacheDict.Remove(remoteFile);                }            }            CreateDownLoadTask(remoteFile, getFtpFunc(), callback);        }        void CreateDownLoadTask(string remoteFile, MyFtp myFtp, EventHandler<CacheFileEventArgs> callBack)        {            lock (_cacheTaskLock)            {                bool exist = _cacheTaskDict.ContainsKey(remoteFile);                AddCallBackToDictNoLock(remoteFile, callBack);                if (exist == false)                {                    Task.Factory.StartNew(() =>                    {                        DownloadFileWork(remoteFile, myFtp, callBack);                    }, TaskCreationOptions.PreferFairness);                }            }        }        void DownloadFileWork(string remoteFile, MyFtp myFtp, EventHandler<CacheFileEventArgs> callback)        {            string localFile = Path.Combine(CacheDir, Guid.NewGuid().ToString() + Path.GetExtension(remoteFile));            string path = Path.GetDirectoryName(localFile);            if (Directory.Exists(path) == false)            {                Directory.CreateDirectory(path);            }            var eventArgs = new CacheFileEventArgs();            try            {                bool dlRet = myFtp.DownLoad(remoteFile, localFile);                if (dlRet && File.Exists(localFile))                {                    var cacheModel = new CacheFileModel()                    {                        RemoteFile = remoteFile,                        LocalFile = localFile                    };                    eventArgs = new CacheFileEventArgs(cacheModel);                    AddCacheData(cacheModel);                }            }            finally            {                try                {                    InvokeCallBack(remoteFile, eventArgs);                }                finally                {                    RemoveCallBack(remoteFile);                }            }        }        void AddCallBackToDictNoLock(string remoteFile, EventHandler<CacheFileEventArgs> callback)        {            if (_cacheTaskDict.ContainsKey(remoteFile) == false)                _cacheTaskDict.Add(remoteFile, new WeakDelegateCollection<CacheFileEventArgs>());            var weakEvent = _cacheTaskDict[remoteFile];            weakEvent.WeakEvent += callback;        }        void RemoveCallBack(string remoteFile)        {            lock (_cacheTaskLock)            {                if (_cacheTaskDict.ContainsKey(remoteFile))                    _cacheTaskDict.Remove(remoteFile);            }        }        void InvokeCallBack(string remoteFile, CacheFileEventArgs args)        {            lock (_cacheTaskLock)            {                if (_cacheTaskDict.ContainsKey(remoteFile) == false)                {                    return;                }                _cacheTaskDict[remoteFile].Invoke(this, args);            }        }    }}

 

【C#】缓存数据