zoukankan      html  css  js  c++  java
  • OutputCacheProvider OutputCache的一点点认识

    在asp.net4.0后我们可以实现自己的OutputCacheProvider来控制缓存的位置了,但是我发现很多人多OutputCacheProvider的调用并不是很清楚。首先我们要知道缓存是在哪里注册的。答案是OutputCacheModule

    void IHttpModule.Init(HttpApplication app)
    {
        if (RuntimeConfig.GetAppConfig().OutputCache.EnableOutputCache)
        {
            app.ResolveRequestCache += new EventHandler(this.OnEnter);
            app.UpdateRequestCache += new EventHandler(this.OnLeave);
        }
    }

    (RuntimeConfig.GetAppConfig().OutputCache.EnableOutputCache这句很明白检查我们的配置,看看你是否启用缓存。OnEnter是在处理前读取缓存数据,处理后设置缓存。

    那么先让我们看看OnEnter的方法把,我把里面多数代码删除 只留主要的结果。

     internal void OnEnter(object source, EventArgs eventArgs)
        {
            this._key = null;       
            string str;
            this._key = str = this.CreateOutputCachedItemKey(context, null);
            object obj2 = OutputCache.Get(str);

    if (obj2 != null)
       {
                    CachedVary cachedVary = obj2 as CachedVary;
    if (cachedVary != null)
                    {
                         str = this.CreateOutputCachedItemKey(context, cachedVary);
                        obj2 = OutputCache.Get(str);}       
                 
                        application.CompleteRequest();
                        return;
                    }
                 return;
                }            
        }

    这里有两次调用obj2 = OutputCache.Get(str),我们来分析一下吧,第一次取出来的数据被转化为cachedVary,这个东西就是保存我们OutputCache中的那些属性配置的一个实例,所以OutputCache不同的属性就会产生不同的cachedVary值,而第二次读取的obj2才是我们真正需要保存的东西,把它取到后做一系列的处理最后结束此次http请求。

    如取值是取2次那么设置也一定是设置2次了。

    internal void OnLeave(object source, EventArgs eventArgs)
        {
          
                CachedVary vary;
                string str;
                vary = new CachedVary(varyByContentEncodings, varyByHeaders, varyByParams, varyByAllParams, currentSettings.VaryByCustom);
      str = this.CreateOutputCachedItemKey(context, vary);


                 HttpRawResponse snapshot = response.GetSnapshot();
                 string kernelCacheUrl = response.SetupKernelCaching(null);
                 Guid cachedVaryId = (vary != null) ? vary.CachedVaryId : Guid.Empty;
                 CachedRawResponse rawResponse = new CachedRawResponse(snapshot, currentSettings, kernelCacheUrl, cachedVaryId);
                 CacheDependency dependencies = response.CreateCacheDependencyForResponse();
        OutputCache.InsertResponse(this._key, vary, str, rawResponse, dependencies, noAbsoluteExpiration, noSlidingExpiration);
                    
            }
        }

    在这里我们看到了CachedVary、CachedRawResponse的两个实例,在这里我们可以确定先前第二次调用obj2 = OutputCache.Get(str)的obj2应该是一个CachedRawResponse实例。而OutputCache的InsertResponse方法:

    internal static void InsertResponse(string cachedVaryKey, CachedVary cachedVary, string rawResponseKey, CachedRawResponse rawResponse, CacheDependency dependencies, DateTime absExp, TimeSpan slidingExp)
    {
        OutputCacheProvider provider = GetProvider(HttpContext.Current);  
       provider.Set(cachedVaryKey, cachedVary, Cache.NoAbsoluteExpiration);
        provider.Set(rawResponseKey, entry, absExp);

    }

    我相信大家看到这里就明白了,OutputCache的保存和读取都是操作2个实例,一个是OutputCache配置实例CachedVary ,另一个是真正的数据流CachedRawResponse 

    看到OutputCache的InsertResponse方法这里提到了OutputCacheProvider provider = GetProvider(HttpContext.Current)而在OutputCacheProvider 的Get方法中也调用了这句

    internal static object Get(string key)
    {
        object obj2 = null;
        OutputCacheProvider provider = GetProvider(HttpContext.Current);
        if (provider != null)
        {
            obj2 = provider.Get(key);
            OutputCacheEntry oce = obj2 as OutputCacheEntry;
            if (oce != null)
            {
                if (HasDependencyChanged(false, oce.DependenciesKey, oce.Dependencies, oce.KernelCacheUrl, key, provider.Name))
                {
                    RemoveFromProvider(key, provider.Name);
                    return null;
                }
                obj2 = Convert(oce);
            }
        }
        if (obj2 == null)
        {
            obj2 = HttpRuntime.CacheInternal.Get(key);
        }
        return obj2;
    }

    而OutputCache的GetProvider的方法干什么的我想我就不提了,相信大家都会明白。

    所以要实现自定义的缓存,可以有两种方案分别是实现自己的OutputCacheProvider和注册自己OutputCacheModule

        public class MemoryCacheProvider : OutputCacheProvider
        { 
            public override object Add(string key, object entry, DateTime utcExpiry)
            {
                return null;
            }
    
            public override object Get(string key)
            {
                return null;
            }
    
            public override void Set(string key, object entry, DateTime utcExpiry)
            {
            }
    
            public override void Remove(string key)
            {
            }
        }
      
    public class CustOutputCacheModule : IHttpModule
        {
            public void Dispose()
            {
            }
    
            public void Init(HttpApplication context)
            {
                context.ResolveRequestCache += new EventHandler(context_ResolveRequestCache);
                context.UpdateRequestCache += new EventHandler(context_UpdateRequestCache);
            }
    
            void context_UpdateRequestCache(object sender, EventArgs e)
            {  
            }
    
            void context_ResolveRequestCache(object sender, EventArgs e)
            {          
            }
        }
    

      相应的配置是

     <caching>
          <outputCache defaultProvider="ChannelInMemory">
            <providers>
                <add name="ChannelInMemory" type="MvcApp.MemoryCacheProvider,MvcApp" />
              </providers>
          </outputCache>
        </caching>


        <httpModules>
          <remove name="OutputCache"/>
          <add name="OutputCache" type="MvcApp.CustOutputCacheModule" />
        </httpModules>

  • 相关阅读:
    leetcode刷题 557~
    Unity正交相机智能包围物体(组)方案
    Embedded Browser(ZFBrowser)使用相关问题
    Unity性能优化
    sipp的使用
    Elment清除表单验证,防止报错小技巧
    git常用命令(干货)
    文本单词one-hot编码
    86. 分隔链表 链表
    5638. 吃苹果的最大数目 优先队列
  • 原文地址:https://www.cnblogs.com/Leo_wl/p/2759397.html
Copyright © 2011-2022 走看看