• 缓存


    缓存的方式有很多中:

    Output Caching 输出缓存

    Fragment Caching

    Data Caching

    SQL Cache

    Cache Configuration 配置缓存

    一、Output Caching输出缓存有两种方法,一种是基于底层的API技术,一种是基于高层的@OutputCaching。

    一旦Output Caching被定制过,网页第一次被访问过的时候就回生成cache,直至请求过期为止。

    不说那么多了,先看下petshop中是怎么使用页面缓存的把,嗯,错了,petshop是没使用这种缓存的。那么Output Caching缓存该怎么做呢?

    <%@ OutputCache Duration="60" VaryByParam="*" %>

    其中Duration是对缓存的页面设置过期时间。VaryByParam应该是指定参数吧,*号表示对所以内容都缓存吧。

    她有使用Fragment Caching,即片段缓存。

    但其实质跟页面缓存差不多。

    petshop的片段缓存不是单纯的缓存,他还用到了SQL Cache,这是.net的新特性,这个缓存对象可以很好解决数据库变化对已缓存页面的改变(这里不多说)。

    就拿ProductsControl.ascx这个控件来说把:

    在前台导入页面设置:<%@ OutputCache Duration="100000" VaryByParam="page;categoryId" %>

    为何VaryByParam的值是page和categoryId呢?categoryId是根据类别来判断要显示的product。但是page我就不明白了(待续)。

    下面是ProductsControl.ascx.cs的代码:

    public partial class ProductsControl : System.Web.UI.UserControl {
    
            /// <summary>
            /// Rebind control 
            /// </summary>
            protected void PageChanged(object sender, DataGridPageChangedEventArgs e) {
                //reset index
                productsList.CurrentPageIndex = e.NewPageIndex;
    
                //get category id
                string categoryKey = Request.QueryString["categoryId"];
    
                //bind data
                Product product = new Product();
                productsList.DataSource = product.GetProductsByCategory(categoryKey);
                productsList.DataBind();
    
            }
    
            /// <summary>
            /// Add cache dependency
            /// </summary>
            protected void Page_Load(object sender, EventArgs e) {
                this.CachePolicy.Dependency = DependencyFacade.GetProductDependency();
            }
        }
    

    其中对数据的绑定是没有什么变化,最重要的要看page_Load的:

    this.CachePolicy.Dependency = DependencyFacade.GetProductDependency();
    增加了这句就可以对数据库的表进行实时增删改监控(用词不当吧)吧。

    但是petshop还为我们展示了另外一种缓存方法,这种方法要叫什么呢?我查了下应该就是传说中的Date Cache(数据缓存)吧:

    且看他们是怎么来做滴(我就拿CategoryDataProxy.cs来说明吧),下面就是这个类的一个方法了:

    public static IList<CategoryInfo> GetCategories() {
    
                Category cat = new Category();
    
                if (!enableCaching)
                    return cat.GetCategories();
    
                string key = "category_all";
                IList<CategoryInfo> data = (IList<CategoryInfo>)HttpRuntime.Cache[key];
    
                // Check if the data exists in the data cache
                if (data == null) {
                    // If the data is not in the cache then fetch the data from the business logic tier
                    data = cat.GetCategories();
    
                    // Create a AggregateCacheDependency object from the factory
                    AggregateCacheDependency cd = DependencyFacade.GetCategoryDependency();
    
                    // Store the output in the data cache, and Add the necessary AggregateCacheDependency object
                    HttpRuntime.Cache.Add(key, data, cd, DateTime.Now.AddHours(categoryTimeout), Cache.NoSlidingExpiration, CacheItemPriority.High, null);
                }
    
                return data;
            }
    

    其中:private static readonly bool enableCaching = bool.Parse(ConfigurationManager.AppSettings["EnableCaching"]);//true
    这种缓存机制是最原始的把,首先我们要从cache[key]就键中找值,如果没有就缓存起来,这种数据缓存在petshop广泛应用。

    这边还是来讲讲那个Sql Cache吧,那么首先要先对数据库进行配置,就是对要监控的表进行配置吧:

    以PetShop 4.0为例,数据库名为MSPetShop4,则命令为:

    aspnet_regsql -S localhost -E -d MSPetShop4 -ed

    以下是该工具的命令参数说明:
    -?  显示该工具的帮助功能;
    -S  后接的参数为数据库服务器的名称或者IP地址;
    -U  后接的参数为数据库的登陆用户名;
    -P  后接的参数为数据库的登陆密码;
    -E  当使用windows集成验证时,使用该功能;
    -d  后接参数为对哪一个数据库采用SqlCacheDependency功能;
    -t  后接参数为对哪一个表采用SqlCacheDependency功能;
    -ed  允许对数据库使用SqlCacheDependency功能;
    -dd  禁止对数据库采用SqlCacheDependency功能;
    -et  允许对数据表采用SqlCacheDependency功能;
    -dt  禁止对数据表采用SqlCacheDependency功能;
    -lt  列出当前数据库中有哪些表已经采用sqlcachedependency功能。

    以上面的命令为例,说明将对名为MSPetShop4的数据库采用SqlCacheDependency功能,且SQL Server采用了windows集成验证方式。我们还可以对相关的数据表执行aspnet_regsql命令,如:
    aspnet_regsql -S localhost -E -d MSPetShop4 -t Item -et
    aspnet_regsql -S localhost -E -d MSPetShop4 -t Product -et
    aspnet_regsql -S localhost -E -d MSPetShop4 -t Category -et

    当执行上述的四条命令后,aspnet_regsql工具会在MSPetShop4数据库中建立一个名为AspNet_SqlCacheTablesForChangeNotification的新数据库表。

     

    具体情况请参考petshop的数据库petshop4。完。

     

    最后补充一个API缓存(应该是对应上面的sql cache 吧)

    其实这种缓存是最原始的缓存吧,先看下在Cache中存储数据的最简单的方法就是使用一个键为其赋值,就像HashTable或Dictionary对象一样: 
       
      Cache["key"] = "value"。

    具体我们可以看下petshop中的SQLHelper中对SQLParameter的缓存吧:

    首先定义了:paramcache的散型变量        private static Hashtable parmCache = Hashtable.Synchronized(new Hashtable());

    其次,添加缓存:  

           /// <summary>
            /// add parameter array to the cache
            /// </summary>
            /// <param name="cacheKey">Key to the parameter cache</param>
            /// <param name="cmdParms">an array of SqlParamters to be cached</param>
            public static void CacheParameters(string cacheKey, params SqlParameter[] commandParameters) {
                parmCache[cacheKey] = commandParameters;//将传过来的SqlParmeter参数存放在散列表中
            }

     

    再次,调用。

            /// <summary>
            /// 检索HashTable的参数 HashTable是一个散列值
            /// </summary>
            /// <param name="cacheKey">key used to lookup parameters</param>
            /// <returns>Cached SqlParamters array</returns>
            public static SqlParameter[] GetCachedParameters(string cacheKey) {
                SqlParameter[] cachedParms = (SqlParameter[])parmCache[cacheKey];//查看散列表中是否有这个键值

                if (cachedParms == null)
                    return null;

                SqlParameter[] clonedParms = new SqlParameter[cachedParms.Length];//为什么要复制我就不知道了

                for (int i = 0, j = cachedParms.Length; i < j; i++)
                    clonedParms[i] = (SqlParameter)((ICloneable)cachedParms[i]).Clone();//这种复制是无法正确判断是深度复制还是浅度复制 但这并不重要

                return clonedParms;
            }


  • 相关阅读:
    阿里fastjson工具类
    poi导出excel2007版本
    java 利用poi 实现excel合并单元格后出现边框有的消失的解决方法
    spring整合atomikos实现分布式事务
    彻底理解ThreadLocal
    kubernetes架构和组件
    Promethues实战-简易教程系列
    Celery
    对称加密,非对称加密,证书机制
    Git diff
  • 原文地址:https://www.cnblogs.com/huaizuo/p/2179191.html
Copyright © 2020-2023  润新知