永久免费看黄A片无码软件,japanese 在线观看国产,强奷高H猛烈失禁潮喷播放,亚洲成精品自拍

rexian

咨詢(xún)電話(huà):023-6276-4481

熱門(mén)文章

聯(lián)系方式

電 話(huà):023-6276-4481

郵箱:broiling@qq.com

地址:重慶市南岸區(qū)亞太商谷6幢25-2

當(dāng)前位置:網(wǎng)站首頁(yè) > 技術(shù)文章 > 適合ASP.NET MVC的視圖片斷緩存方式

適合ASP.NET MVC的視圖片斷緩存方式

編輯:kangkang 發(fā)表時(shí)間:2017-07-28 08:58:36
kangkang

說(shuō)到網(wǎng)站性能優(yōu)化,沒(méi)有什么比“緩存”更重要了。即便是某些朋友口中念念不忘的“靜態(tài)頁(yè)”,說(shuō)到底也只是緩存了整張頁(yè)面內(nèi)容而已。但是,顯然這樣大粒度的緩存策略,在如今“牽一發(fā)而動(dòng)全身”的Web 2.0站點(diǎn)中幾乎是無(wú)法使用的。試想,在Twitter中的某個(gè)名人被數(shù)十萬(wàn)人訂閱,那么他發(fā)一條消息,難道此時(shí)網(wǎng)站要去修改數(shù)十萬(wàn)用戶(hù)的靜態(tài)頁(yè)面?因此,我們需要粒度更小的緩存。而比“整頁(yè)緩存”粒度小一號(hào)的緩存,便是所謂“視圖片斷緩存”了。

視圖片斷緩存非常重要,因?yàn)樗彺娴囊彩琼?yè)面內(nèi)容,這表示它比更低級(jí)別的緩存更有效率,也比靜態(tài)頁(yè)等整頁(yè)內(nèi)容緩存的適用面要大得多。在ASP.NET WebForm模型中提供了控件級(jí)別的緩存,我們可以為控件標(biāo)記輸出緩存策略,這樣控件便不會(huì)每次都完整執(zhí)行一遍。當(dāng)然這個(gè)策略還不夠靈活,因?yàn)樗彺娴淖钚卧恰翱丶保皇琼?yè)面中任意的部分。因此我在一年多前提出了一個(gè)CachePanel,由它包裝的頁(yè)面內(nèi)容都可以被緩存,無(wú)論其內(nèi)部是控件還是普通輸出的內(nèi)容。在實(shí)際生產(chǎn)過(guò)程中,CachePanel起到了非常重要的作用,許多場(chǎng)景下只要在頁(yè)面中包裹一個(gè)<ext:CachePanel runat="server" />,性能立即就有了質(zhì)的飛躍。

只可惜,在如今ASP.NET MVC的時(shí)代無(wú)法直接使用CachePanel這樣的服務(wù)器端控件。因?yàn)镃achePanel需要服務(wù)器端代碼的配合,而ASP.NET MVC中的頁(yè)面只是“視圖模板”,除了呈現(xiàn)之外就不應(yīng)該有其他職責(zé)。因此,我們必須提出一種脫離于后端代碼的“標(biāo)記”方式,將視圖中的內(nèi)容片斷進(jìn)行隨意地緩存。在RailsDjango中都有類(lèi)似的特性,但ASP.NET MVC甚至在2.0的Road Map中還沒(méi)有包含這一功能,于是我們只能自己動(dòng)手豐衣足食。不過(guò)有了ASP.NET WebForm作為強(qiáng)大的視圖引擎,加這樣的功能簡(jiǎn)直是舉手之勞:

public static class CacheExtensions{    public static string Cache(        this HtmlHelper htmlHelper,        string cacheKey,        CacheDependency cacheDependencies,        DateTime absoluteExpiration,        TimeSpan slidingExpiration,        Func<object> func)
    {        var cache = htmlHelper.ViewContext.HttpContext.Cache;        var content = cache.Get(cacheKey) as string;        if (content == null)
        {
            content = func().ToString();
            cache.Insert(cacheKey, content, cacheDependencies, absoluteExpiration, slidingExpiration);
        }        return content;
    }
}

我們?yōu)镠tmlHelper增加了一個(gè)Cache擴(kuò)展方法,接受一些緩存參數(shù)(緩存鍵,絕對(duì)過(guò)期時(shí)間,偏移過(guò)期時(shí)間),以及一個(gè)生成緩存內(nèi)容的Func<object>委托。Cache方法的邏輯非常簡(jiǎn)單:首先根據(jù)緩存鍵來(lái)獲取內(nèi)容,如果存在則直接返回,否則即調(diào)用委托對(duì)象獲得新內(nèi)容,并將其放入緩存。這樣在緩存命中的情況下,委托的開(kāi)銷(xiāo)便可以節(jié)省下來(lái)了。

例如,我們可以使用這樣的代碼進(jìn)行測(cè)試:

Before Rendering:<%= DateTime.Now %><br />Rendering:<%= Html.Cache("Now", null, DateTime.Now.AddSeconds(60), Cache.NoSlidingExpiration,
    () => { System.Threading.Thread.Sleep(5000); return DateTime.Now; }) %><br />After Rendering:<%= DateTime.Now %>

在實(shí)際情況中,我們是不會(huì)在代碼中調(diào)用Thread.Sleep方法的,不過(guò)這里我們需要模擬一段開(kāi)銷(xiāo),因此通過(guò)暫停當(dāng)前線(xiàn)程來(lái)實(shí)現(xiàn)時(shí)間消耗。于是我們第一次打開(kāi)頁(yè)面:

Before Rendering: 2009/9/17 16:52:37 
Rendering: 2009/9/17 16:52:42 
After Rendering: 2009/9/17 16:52:42

從結(jié)果中可以看出,Before Rendering和After Rendering相差了5秒鐘,這就是Thread.Sleep(5000)的效果。但是如果您在60秒以?xún)?nèi)再次刷新頁(yè)面,便可以看到緩存的效果:

Before Rendering: 2009/9/17 16:52:55 
Rendering: 2009/9/17 16:52:42 
After Rendering: 2009/9/17 16:52:55

可以看出,Rendering階段顯示的還是剛才的時(shí)間,而B(niǎo)efore Rendering和After Rendering是即時(shí)更新的。此外,由于Cache方法將Thread.Sleep(5000)的開(kāi)銷(xiāo)節(jié)省了下來(lái),因此Before Rendering和After Rendering兩個(gè)階段打印出的時(shí)間完全相同。

怎么樣,簡(jiǎn)單吧。不過(guò)您應(yīng)該會(huì)感到疑惑,這不是我們想要的結(jié)果啊,我們想緩存的是頁(yè)面上的一個(gè)片斷,但是現(xiàn)在必須將被緩存的內(nèi)容作為一個(gè)完整的字符串輸出,那么我們又該如何實(shí)現(xiàn)呢?難道我們要這么寫(xiě)嗎?

<%= Html.Cache(..., () => "<span style=\"color:red;\">" + Model.Title + "</span>") %>

當(dāng)然不可能這樣。如果只是這樣的話(huà),那么這個(gè)Cache的可用性毫無(wú)疑問(wèn)會(huì)非常低。因此,我們還需要尋找更好的解決方案——關(guān)于這點(diǎn),我們下次再聊。而目前的Cache方法,最方便的輸出大端頁(yè)面內(nèi)容的做法則是將內(nèi)容放在一個(gè)Partial View中,然后使用Html.Partial方法輸出內(nèi)容:

<%= Html.Cache(..., () => Html.Partial("MyPartialViewToCache")) %>

請(qǐng)注意,我們這里使用的是擴(kuò)展后的Partial方法,而不是自帶的RenderPartial。之前我們談過(guò)WebForm頁(yè)面的輸出方式,而RenderPartial方法是直接向Response.Output輸出頁(yè)面內(nèi)容,因此我們無(wú)法將其捕捉為一個(gè)字符串。不過(guò),之前文章中的Partial方法是“山寨”版本,而符合“標(biāo)準(zhǔn)”的Partial方法實(shí)現(xiàn)已經(jīng)包含在MvcPatch項(xiàng)目中。如果您感興趣的話(huà),可以獲取它的源代碼并編譯。我這段時(shí)間在一部分一部分地將以前項(xiàng)目中較為通用的擴(kuò)展及修改提取至MvcPatch中,希望可以使MvcPatch成為一個(gè)可復(fù)用的強(qiáng)大組件。