相关信息
1.线程安全
在.net中,绝大多数类在实现时,都只是保证静态类型的方法是线程安全, 而不考虑实例方法是线程安全。这也算是一条基本的.NET设计规范原则
所以,这就意味着我们可以在任何地方读写Cache都不用担心Cache的数据在多线程环境下的数据同步问题。 多线程编程中,最复杂的问题就是数据的同步问题,而Cache已经为我们解决了这些问题
2.定义
ASP.NET为了方便我们访问Cache,在HttpRuntime类中加了一个静态属性Cache,这样,我们就可以在任意地方使用Cache的功能
而且,ASP.NET还给它增加了二个“快捷方式”:Page.Cache, HttpContext.Cache,我们通过这二个对象也可以访问到HttpRuntime.Cache
注意:这三者是在访问同一个对象。Page.Cache访问了HttpContext.Cache,而HttpContext.Cache又直接访问System.Web.HttpRuntime.Cache
缓存项的依赖关系
1.依赖其他缓存项
创建多个缓存项,建立依赖关系
当依赖项数据发生变化,被依赖项的缓存自动失效
[Fact] public void Run() { TestOutputHelper.WriteLine("Run Start"); Cache objCache = HttpRuntime.Cache; objCache.Insert("ParentKey", $"ParentKey-{Guid.NewGuid()}"); objCache.Insert("OtherKey", $"OtherKey-{Guid.NewGuid()}"); CacheDependency dep = new CacheDependency(null, new string[] { "ParentKey", "OtherKey" }); objCache.Insert("ChildrenKey", DateTime.Now.ToString(), dep , Cache.NoAbsoluteExpiration, Cache.NoSlidingExpiration); WriteLine(objCache); objCache.Insert("ParentKey", Guid.NewGuid().ToString()); WriteLine(objCache); TestOutputHelper.WriteLine("Run End"); }
2.依赖文件
配置文件发生变化,不需要重启服务器,程序能立刻获取最新参数并运行
简而言之:热加载
[Fact] public void Run2() { TestOutputHelper.WriteLine("Run Start"); var boo = false; do { DependentFileString(); Thread.Sleep(1000 * 3); } while (!boo); TestOutputHelper.WriteLine("Run End"); } private void DependentFileString() { // 首先尝试从缓存中获取运行参数 var cacheKey = "DependentFileKey"; var config = HttpRuntime.Cache[cacheKey]?.ToString(); // 缓存中没有,则从文件中加载 if (config == null) { string path = @"C:\Working\README.txt"; config = File.ReadAllText(path, Encoding.UTF8); // 把从文件中读到的结果放入缓存,并设置与文件的依赖关系。 CacheDependency dep = new CacheDependency(path); // 如果参数较复杂,与多个文件相关 // 那么也可以使用下面的方式,传递多个文件路径。 //CacheDependency dep = new CacheDependency(new string[] { path }); HttpRuntime.Cache.Insert(cacheKey, config, dep); } TestOutputHelper.WriteLine($"config:{config.ToJson()}"); }
缓存移除通知
缓存移除“前”和“后”通过委托触发通知
/// <summary> /// 设置当前应用程序指定CacheKey的Cache值: 带回调函数 /// </summary> /// <param name="CacheKey">The cache key.</param> /// <param name="objObject">The obj object.</param> /// <param name="absoluteExpiration">The absolute expiration.</param> /// <param name="slidingExpiration">The sliding expiration.</param> public static void SetCache(string CacheKey, object objObject, DateTime absoluteExpiration, TimeSpan slidingExpiration, CacheItemPriority priority, CacheItemRemovedCallback onRemoveCallback) { Cache objCache = HttpRuntime.Cache; objCache.Insert(CacheKey, objObject, null, absoluteExpiration, slidingExpiration, priority, onRemoveCallback); }
调用
/// <summary> /// 保存文件 /// </summary> /// <param name="workbook"></param> /// <param name="filePath"></param> /// <param name="fileName"></param> public static void SaveTofle(IWorkbook workbook, string filePath, string fileName) { if (!Directory.Exists(filePath)) Directory.CreateDirectory(filePath); var completePath = Path.Combine(filePath, fileName); using (FileStream fs = new FileStream(completePath, FileMode.OpenOrCreate, FileAccess.Write)) { workbook.Write(fs); } // 自动删除文件:五分钟 var CacheKey = $"Excel_{fileName}"; DataCacheHelper.SetCache(CacheKey, completePath, DateTimeExtend.GetValidDate.AddMinutes(5), TimeSpan.Zero, CacheItemPriority.NotRemovable, RemoveSaveFile); } /// <summary> /// 自动删除文件 /// </summary> /// <param name="key"></param> /// <param name="value"></param> /// <param name="reason"></param> private static void RemoveSaveFile(string key, object value, CacheItemRemovedReason reason) { if (reason != CacheItemRemovedReason.Expired) return; var completePath = value.ToString(); if (File.Exists(completePath)) File.Delete(completePath); }
Link:
细说 ASP.NET Cache 及其高级用法