Sdílet prostřednictvím


Ukládání dat do mezipaměti při spuštění aplikace (C#)

Scott Mitchell

Stáhnout PDF

V každé webové aplikaci budou některá data často používána a některá budou použita jen zřídka. Výkon naší ASP.NET aplikace můžeme zlepšit tak, že předem načítáme často používaná data– techniku známou jako ukládání do mezipaměti. Tento kurz ukazuje jeden přístup k proaktivnímu načítání, kterým je načtení dat do mezipaměti při spuštění aplikace.

Úvod

Dva předchozí kurzy se zabývaly ukládáním dat do mezipaměti ve vrstvách prezentace a ukládání do mezipaměti. V části Ukládání dat do mezipaměti pomocí objektu ObjectDataSource jsme se podívali na použití funkcí ukládání do mezipaměti ObjectDataSource k ukládání dat do mezipaměti v prezentační vrstvě. Ukládání dat do mezipaměti v architektuře prozkoumalo ukládání do mezipaměti v nové samostatné vrstvě ukládání do mezipaměti. V obou těchto kurzech se při práci s mezipamětí dat použilo reaktivní načítání . Při reaktivním načítání systém při každém vyžádání dat nejprve zkontroluje, jestli jsou v mezipaměti. Pokud ne, vezme data z původního zdroje, například z databáze, a uloží je do mezipaměti. Hlavní výhodou reaktivního načítání je jeho snadná implementace. Jednou z jeho nevýhod je nerovnoměrný výkon napříč požadavky. Představte si stránku, která používá vrstvu ukládání do mezipaměti z předchozího kurzu k zobrazení informací o produktu. Pokud je tato stránka navštívena poprvé nebo je navštívena poprvé po vyřazení dat uložených v mezipaměti z důvodu omezení paměti nebo dosažení zadaného vypršení platnosti, musí být data načtena z databáze. Proto budou tyto žádosti uživatelů trvat déle než požadavky uživatelů, které může mezipaměť obsluhovat.

Proaktivní načítání poskytuje alternativní strategii správy mezipaměti, která vyrovnává výkon požadavků tím, že načítá data uložená v mezipaměti dříve, než je potřeba. Proaktivní načítání obvykle používá nějaký proces, který buď pravidelně kontroluje, nebo je upozorněn, když došlo k aktualizaci podkladových dat. Tento proces pak aktualizuje mezipaměť, aby byla stále aktuální. Proaktivní načítání je užitečné zejména v případě, že podkladová data pocházejí z pomalého připojení k databázi, webové služby nebo některého jiného obzvláště pomalého zdroje dat. Implementace tohoto přístupu k proaktivnímu načítání je ale obtížnější, protože vyžaduje vytvoření, správu a nasazení procesu kontroly změn a aktualizace mezipaměti.

Další variantou proaktivního načítání a typem, který v tomto kurzu prozkoumáme, je načítání dat do mezipaměti při spuštění aplikace. Tento přístup je zvlášť užitečný pro ukládání statických dat do mezipaměti, jako jsou záznamy ve vyhledávacích tabulkách databáze.

Poznámka

Podrobnější pohled na rozdíly mezi proaktivním a reaktivním načítáním a seznam výhod, nevýhod a doporučení k implementaci najdete v části Správa obsahu mezipamětiv průvodci architekturou ukládání do mezipaměti pro aplikace .NET Framework.

Krok 1: Určení dat, která se mají ukládat do mezipaměti při spuštění aplikace

Příklady ukládání do mezipaměti využívající reaktivní načítání, které jsme prozkoumali v předchozích dvou kurzech, dobře fungují s daty, která se mohou pravidelně měnit a jejich vygenerování netrvá příliš dlouho. Pokud se ale data uložená v mezipaměti nikdy nezmění, je vypršení platnosti použité při reaktivním načítání nadbytečné. Podobně platí, že pokud generování dat uložených v mezipaměti trvá příliš dlouho, pak uživatelé, jejichž požadavky zjistí, že mezipaměť je prázdná, budou muset na načtení podkladových dat vydržet dlouhé čekání. Zvažte ukládání statických dat a dat do mezipaměti, která se při spuštění aplikace vygenerují mimořádně dlouho.

I když databáze mají mnoho dynamických, často se měnících hodnot, většina má také poměrně velké množství statických dat. Například prakticky všechny datové modely mají jeden nebo více sloupců, které obsahují konkrétní hodnotu z pevné sady voleb. Tabulka Patients databáze může obsahovat PrimaryLanguage sloupec, jehož sada hodnot může být angličtina, španělština, francouzština, ruština, japonština atd. Tyto typy sloupců se často implementují pomocí vyhledávacích tabulek. Místo toho, aby se v tabulce ukládaly řetězce v Patients angličtině nebo francouzštině, vytvoří se druhá tabulka, která obvykle obsahuje dva sloupce – jedinečný identifikátor a popis řetězce – se záznamem pro každou možnou hodnotu. Sloupec PrimaryLanguage v Patients tabulce ukládá odpovídající jedinečný identifikátor ve vyhledávací tabulce. Na obrázku 1 je primárním jazykem pacienta John Doe angličtina, zatímco jazyk Ed Johnson je ruština.

Tabulka Jazyky je vyhledávací tabulka používaná tabulkou Pacienti.

Obrázek 1: Tabulka Languages je vyhledávací tabulka používaná tabulkou Patients

Uživatelské rozhraní pro úpravy nebo vytvoření nového pacienta by obsahovalo rozevírací seznam povolených jazyků naplněných záznamy v Languages tabulce. Bez ukládání do mezipaměti musí systém při každé návštěvě tohoto rozhraní dotazovat tabulku Languages . To je zbytečné a zbytečné, protože hodnoty vyhledávací tabulky se mění velmi zřídka, pokud vůbec.

Data bychom mohli uložit do Languages mezipaměti pomocí stejných technik reaktivního načítání, které jsme prozkoumali v předchozích kurzech. Reaktivní načítání ale používá vypršení platnosti na základě času, které není pro data statické vyhledávací tabulky potřeba. Zatímco ukládání do mezipaměti pomocí reaktivního načítání by bylo lepší než ukládání do mezipaměti vůbec, nejlepší přístup by bylo proaktivně načíst data vyhledávací tabulky do mezipaměti při spuštění aplikace.

V tomto kurzu se podíváme na to, jak ukládat data vyhledávací tabulky a další statické informace do mezipaměti.

Krok 2: Prozkoumání různých způsobů ukládání dat do mezipaměti

Informace je možné ukládat do mezipaměti v ASP.NET aplikaci prostřednictvím kódu programu pomocí různých přístupů. Způsob použití datové mezipaměti jsme už viděli v předchozích kurzech. Alternativně lze objekty ukládat do mezipaměti prostřednictvím kódu programu pomocí statických členů nebo stavu aplikace.

Při práci s třídou se obvykle musí nejprve vytvořit instance třídy, aby bylo možné získat přístup k jejím členům. Pokud například chcete vyvolat metodu z jedné z tříd v naší vrstvě obchodní logiky, musíme nejprve vytvořit instanci třídy :

ProductsBLL productsAPI = new ProductsBLL();
productsAPI.SomeMethod();
productsAPI.SomeProperty = "Hello, World!";

Než můžeme vyvolat SomeMethod nebo pracovat s SomeProperty, musíme nejprve vytvořit instanci třídy pomocí klíčového new slova . SomeMethod a SomeProperty jsou přidruženy ke konkrétní instanci. Životnost těchto členů je svázaná s životností jejich přidruženého objektu. Statické členy jsou na druhé straně proměnné, vlastnosti a metody, které jsou sdíleny mezi všemi instancemi třídy, a proto mají životnost tak dlouhou dobu jako třída. Statické členy jsou označeny klíčovým slovem static.

Kromě statických členů je možné data ukládat do mezipaměti pomocí stavu aplikace. Každá aplikace ASP.NET udržuje kolekci názvů a hodnot, která se sdílí mezi všemi uživateli a stránkami aplikace. K této kolekci je možné přistupovat pomocí HttpContextvlastnosti třídy Applicationa používat ji z třídy kódu na pozadí ASP.NET stránky, například takto:

Application["key"] = value;
object value = Application["key"];

Mezipaměť dat poskytuje mnohem bohatší rozhraní API pro ukládání dat do mezipaměti, poskytuje mechanismy pro vypršení platnosti na základě času a závislostí, priority položek mezipaměti atd. U statických členů a stavu aplikace musí tyto funkce ručně přidat vývojář stránky. Při ukládání dat do mezipaměti při spuštění aplikace po celou dobu životnosti aplikace jsou však výhody mezipaměti dat moot. V tomto kurzu se podíváme na kód, který používá všechny tři techniky pro ukládání statických dat do mezipaměti.

Krok 3: Ukládání dat tabulky doSuppliersmezipaměti

Databázové tabulky Northwind, které jsme k dnešnímu dni implementovali, neobsahují žádné tradiční vyhledávací tabulky. Čtyři tabulky DataTable implementované v dal všechny tabulky modelu, jejichž hodnoty nejsou statické. Místo toho, abychom trávili čas přidáním nové tabulky DataTable do DAL a pak novou třídu a metody do knihovny BLL, pro účely tohoto kurzu jen předstírejme, že Suppliers data tabulky jsou statická. Proto bychom tato data mohli při spuštění aplikace uložit do mezipaměti.

Začněte tím, že ve CL složce vytvoříte novou třídu s názvem StaticCache.cs .

Vytvoření třídy StaticCache.cs ve složce CL

Obrázek 2: Vytvoření StaticCache.cs třídy ve CL složce

Potřebujeme přidat metodu, která načte data při spuštění do příslušného úložiště mezipaměti, a také metody, které vracejí data z této mezipaměti.

[System.ComponentModel.DataObject]
public class StaticCache
{
    private static Northwind.SuppliersDataTable suppliers = null;
    public static void LoadStaticCache()
    {
        // Get suppliers - cache using a static member variable
        SuppliersBLL suppliersBLL = new SuppliersBLL();
        suppliers = suppliersBLL.GetSuppliers();
    }
    [DataObjectMethodAttribute(DataObjectMethodType.Select, true)]
    public static Northwind.SuppliersDataTable GetSuppliers()
    {
        return suppliers;
    }
}

Výše uvedený kód používá statickou členskou proměnnou , supplierskterá uchovává výsledky z SuppliersBLL metody třídy GetSuppliers() , která je volána z LoadStaticCache() metody . Metoda LoadStaticCache() se má volat během spuštění aplikace. Jakmile se tato data načtou při spuštění aplikace, může každá stránka, která potřebuje pracovat s daty dodavatelů, volat metodu StaticCache třídy GetSuppliers() . Proto volání databáze pro získání dodavatelů proběhne pouze jednou při spuštění aplikace.

Místo použití statické členské proměnné jako úložiště mezipaměti bychom mohli alternativně použít stav aplikace nebo mezipaměť dat. Následující kód ukazuje třídu přeusněnou tak, aby používala stav aplikace:

[System.ComponentModel.DataObject]
public class StaticCache
{
    public static void LoadStaticCache()
    {
        // Get suppliers - cache using application state
        SuppliersBLL suppliersBLL = new SuppliersBLL();
        HttpContext.Current.Application["key"] = suppliersBLL.GetSuppliers();
    }
    [DataObjectMethodAttribute(DataObjectMethodType.Select, true)]
    public static Northwind.SuppliersDataTable GetSuppliers()
    {
        return HttpContext.Current.Application["key"] as Northwind.SuppliersDataTable;
    }
}

V LoadStaticCache()nástroji se informace o dodavateli ukládají do klíče proměnné aplikace. Vrátí se jako odpovídající typ (Northwind.SuppliersDataTable) z GetSuppliers(). I když je stav aplikace přístupný ve třídách kódu na pozadí ASP.NET stránek pomocí Application["key"], v architektuře musíme k získání aktuálního HttpContextkódu použít HttpContext.Current.Application["key"] .

Podobně lze mezipaměť dat použít jako úložiště mezipaměti, jak ukazuje následující kód:

[System.ComponentModel.DataObject]
public class StaticCache
{
    public static void LoadStaticCache()
    {
        // Get suppliers - cache using the data cache
        SuppliersBLL suppliersBLL = new SuppliersBLL();
        HttpRuntime.Cache.Insert(
          /* key */                "key", 
          /* value */              suppliers, 
          /* dependencies */       null, 
          /* absoluteExpiration */ Cache.NoAbsoluteExpiration, 
          /* slidingExpiration */  Cache.NoSlidingExpiration, 
          /* priority */           CacheItemPriority.NotRemovable, 
          /* onRemoveCallback */   null);
    }
    [DataObjectMethodAttribute(DataObjectMethodType.Select, true)]
    public static Northwind.SuppliersDataTable GetSuppliers()
    {
        return HttpRuntime.Cache["key"] as Northwind.SuppliersDataTable;
    }
}

Pokud chcete přidat položku do mezipaměti dat bez vypršení platnosti na základě času, použijte System.Web.Caching.Cache.NoAbsoluteExpiration jako vstupní parametry hodnoty a System.Web.Caching.Cache.NoSlidingExpiration . Toto konkrétní přetížení metody mezipaměti Insert dat bylo vybráno tak, abychom mohli zadat prioritu položky mezipaměti. Priorita se používá k určení položek, které se mají z mezipaměti vymýt, když je nedostatek dostupné paměti. Tady použijeme prioritu NotRemovable, která zajistí, že tato položka mezipaměti nebude vyčištěna.

Poznámka

Tento kurz ke stažení implementuje StaticCache třídu pomocí přístupu statické členské proměnné. Kód pro techniky stavu aplikace a mezipaměti dat je k dispozici v komentářích v souboru třídy.

Krok 4: Spuštění kódu při spuštění aplikace

Abychom mohli spustit kód při prvním spuštění webové aplikace, musíme vytvořit speciální soubor s názvem Global.asax. Tento soubor může obsahovat obslužné rutiny událostí pro události na úrovni aplikace, relace a požadavku a je to místo, kam můžeme přidat kód, který se spustí při každém spuštění aplikace.

Global.asax Přidejte soubor do kořenového adresáře webové aplikace tak, že v Průzkumník řešení sady Visual Studio kliknete pravým tlačítkem na název projektu webu a zvolíte Přidat novou položku. V dialogovém okně Přidat novou položku vyberte typ položky Globální třída aplikace a potom klikněte na tlačítko Přidat.

Poznámka

Pokud již Global.asax máte soubor v projektu, typ položky Globální třída aplikace nebude uveden v dialogovém okně Přidat novou položku.

Přidejte soubor Global.asax do kořenového adresáře webové aplikace.

Obrázek 3: Přidání Global.asax souboru do kořenového adresáře webové aplikace (kliknutím zobrazíte obrázek v plné velikosti)

Výchozí Global.asax šablona souboru obsahuje pět metod v rámci značky na straně <script> serveru:

  • Application_Start se spustí při prvním spuštění webové aplikace.
  • Application_End se spustí, když se aplikace vypíná.
  • Application_Error spustí se vždy, když aplikace dosáhne neošetřené výjimky.
  • Session_Start se spustí při vytvoření nové relace.
  • Session_End spustí se v případě vypršení platnosti nebo opuštění relace.

Obslužná rutina Application_Start události je volána pouze jednou během životního cyklu aplikace. Aplikace se spustí při prvním vyžádání prostředku ASP.NET z aplikace a poběží až do restartování aplikace. K tomu může dojít mimo jiné úpravou obsahu /Bin složky, úpravou Global.asaxobsahu složky, úpravou obsahu ve App_Code složce nebo úpravou Web.config souboru. Podrobnější informace o životním cyklu aplikace najdete v tématu ASP.NET Přehled životního cyklu aplikace.

Pro tyto kurzy stačí přidat kód do Application_Start metody , takže ostatní odeberte. V Application_Startsouboru jednoduše zavolejte LoadStaticCache() metodu StaticCache třídy, která načte informace o dodavateli a uloží je do mezipaměti:

<%@ Application Language="C#" %>
<script runat="server">
    void Application_Start(object sender, EventArgs e) 
    {
        StaticCache.LoadStaticCache();
    }
</script>

A je to! Při spuštění LoadStaticCache() aplikace metoda vezme informace o dodavateli z BLL a uloží je do statické členské proměnné (nebo jiného úložiště mezipaměti, které jste nakonec ve třídě používali StaticCache ). Chcete-li ověřit toto chování, nastavte zarážku v Application_Start metodě a spusťte aplikaci. Všimněte si, že při spuštění aplikace dojde k zarážce. Následné požadavky však nezpůsobí Application_Start spuštění metody.

Použití zarážky k ověření spouštění obslužné rutiny události Application_Start

Obrázek 4: Použití zarážky k ověření spouštění Application_Start obslužné rutiny události (kliknutím zobrazíte obrázek v plné velikosti).

Poznámka

Pokud při prvním spuštění ladění nenarazíte na Application_Start zarážku, je to proto, že vaše aplikace už byla spuštěna. Vynuťte restartování aplikace úpravou souborů nebo Web.config a zkuste Global.asax to znovu. Můžete jednoduše přidat (nebo odebrat) prázdný řádek na konci jednoho z těchto souborů a rychle restartovat aplikaci.

Krok 5: Zobrazení dat uložených v mezipaměti

V tomto okamžiku StaticCache má třída verzi dat dodavatele uloženou v mezipaměti při spuštění aplikace, ke které lze přistupovat prostřednictvím její GetSuppliers() metody. Pro práci s těmito daty z prezentační vrstvy můžeme použít ObjectDataSource nebo programově vyvolat metodu StaticCache třídy GetSuppliers() z třídy kódu na pozadí ASP.NET stránky. Pojďme se podívat na použití ovládacích prvků ObjectDataSource a GridView k zobrazení informací o dodavateli uložených v mezipaměti.

Začněte otevřením AtApplicationStartup.aspx stránky ve Caching složce . Přetáhněte objekt GridView z panelu nástrojů do návrháře a nastavili jeho ID vlastnost na Suppliers. Dále z inteligentní značky GridView zvolte, že chcete vytvořit nový ObjectDataSource s názvem SuppliersCachedDataSource. Nakonfigurujte ObjectDataSource tak, aby používal metodu StaticCache třídy GetSuppliers() .

Konfigurace objektu ObjectDataSource pro použití třídy StaticCache

Obrázek 5: Konfigurace objektu ObjectDataSource pro použití StaticCache třídy (kliknutím zobrazíte obrázek v plné velikosti)

Použití metody GetSuppliers() k načtení dat dodavatele uložených v mezipaměti

Obrázek 6: Použití GetSuppliers() metody k načtení dat dodavatele uložených v mezipaměti (kliknutím zobrazíte obrázek v plné velikosti)

Po dokončení průvodce sada Visual Studio automaticky přidá boundfields pro všechna datová pole v nástroji SuppliersDataTable. Deklarativní značky GridView a ObjectDataSource by měly vypadat nějak takto:

<asp:GridView ID="Suppliers" runat="server" AutoGenerateColumns="False" 
    DataKeyNames="SupplierID" DataSourceID="SuppliersCachedDataSource" 
    EnableViewState="False">
    <Columns>
        <asp:BoundField DataField="SupplierID" HeaderText="SupplierID" 
            InsertVisible="False" ReadOnly="True" 
            SortExpression="SupplierID" />
        <asp:BoundField DataField="CompanyName" HeaderText="CompanyName" 
            SortExpression="CompanyName" />
        <asp:BoundField DataField="Address" HeaderText="Address" 
            SortExpression="Address" />
        <asp:BoundField DataField="City" HeaderText="City" 
            SortExpression="City" />
        <asp:BoundField DataField="Country" HeaderText="Country" 
            SortExpression="Country" />
        <asp:BoundField DataField="Phone" HeaderText="Phone" 
            SortExpression="Phone" />
    </Columns>
</asp:GridView>
<asp:ObjectDataSource ID="SuppliersCachedDataSource" runat="server" 
    OldValuesParameterFormatString="original_{0}"
    SelectMethod="GetSuppliers" TypeName="StaticCache" />

Obrázek 7 znázorňuje stránku při prohlížení v prohlížeči. Výstup je stejný, pokud jsme nabrali data z třídy BLL SuppliersBLL , ale použití StaticCache třídy vrátí data dodavatele jako uložená v mezipaměti při spuštění aplikace. Toto chování můžete ověřit nastavením zarážek v StaticCache metodě třídy GetSuppliers() .

Data dodavatele uložená v mezipaměti se zobrazují v zobrazení GridView.

Obrázek 7: Data dodavatele uložená v mezipaměti se zobrazují v zobrazení GridView (kliknutím zobrazíte obrázek v plné velikosti)

Souhrn

Většina datových modelů obsahuje poměrně velké množství statických dat, obvykle implementovaných ve formě vyhledávacích tabulek. Vzhledem k tomu, že jsou tyto informace statické, není důvod k trvalému přístupu k databázi pokaždé, když je potřeba tyto informace zobrazit. Vzhledem k jejich statické povaze navíc při ukládání dat do mezipaměti není potřeba vypršení platnosti. V tomto kurzu jsme viděli, jak taková data přijmout a uložit je do mezipaměti dat, stavu aplikace a prostřednictvím statické členské proměnné. Tyto informace se ukládají do mezipaměti při spuštění aplikace a zůstávají v mezipaměti po celou dobu životnosti aplikace.

V tomto kurzu a v předchozích dvou jsme se podívali na ukládání dat do mezipaměti po dobu životnosti aplikace a také na používání vypršení platnosti na základě času. Při ukládání dat databáze do mezipaměti ale může být vypršení platnosti na základě času méně než ideální. Místo pravidelného vyprázdnění mezipaměti by bylo optimální vyřazení položky v mezipaměti pouze při úpravě podkladových dat databáze. Ideální řešení je možné prostřednictvím závislostí mezipaměti SQL, které prozkoumáme v dalším kurzu.

Všechno nejlepší na programování!

O autorovi

Scott Mitchell, autor sedmi knih o ASP/ASP.NET a zakladatel 4GuysFromRolla.com, pracuje s webovými technologiemi Microsoftu od roku 1998. Scott pracuje jako nezávislý konzultant, školitel a spisovatel. Jeho nejnovější kniha je Sams Teach Yourself ASP.NET 2.0 in 24 Hours. Můžete ho zastihnout na mitchell@4GuysFromRolla.comadrese . nebo prostřednictvím jeho blogu, který najdete na adrese http://ScottOnWriting.NET.

Zvláštní poděkování

Tato série kurzů byla zkontrolována mnoha užitečnými recenzenty. Hlavními recenzenty pro tento kurz byli Teresa Murphy a Zack Jones. Chtěli byste si projít své nadcházející články na webu MSDN? Pokud ano, dejte mi řádek na mitchell@4GuysFromRolla.com.