当前位置: 移动技术网 > IT编程>开发语言>.net > OutputCacheProvider OutputCache的一点点认识

OutputCacheProvider OutputCache的一点点认识

2018年09月20日  | 移动技术网IT编程  | 我要评论

聂露勇,蛮后揍扁皇上,总裁来袭豪门联姻

在.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方法中也调用了这句


[csharp]
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; 

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


[csharp]
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) 
    { 
    } 

 
ic 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) 
    {           
    } 

    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="mapp.memorycacheprovider,mvcapp" />
          </providers>
      </outputcache>
    </caching>


    <httpmodules>
      <remove name="outputcache"/>
      <add name="outputcache" type="mvcapp.custoutputcachemodule" />
    </httpmodules>

 

分享到:

如对本文有疑问,请在下面进行留言讨论,广大热心网友会与你互动!! 点击进行留言回复

相关文章:

验证码:
移动技术网