NET Cache高级用法

相关信息

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 及其高级用法

 

上一篇:c#


下一篇:我所知道的CallbackContract in WCF