Caching con ASP.NET
Vediamo quali sono e come funzionano i 3 tipi di cache per le applicazioni web. Esempi e parametri.
Una delle cose da tenere presente nello sviluppo di pagine web dinamiche, è la velocità con cui una pagina viene caricata e mostrata ai visitatori del sito web. Se i dati di una pagina sono frutto di elaborazioni complesse il tempo di caricamento della pagina stessa risulta elevato. Un modo di migliorare le prestazioni di un'applicazione sarebbe quello di archiviare in memoria i dati a cui si accede frequentemente e la cui creazione richiede tempi di elaborazione significativi. Se, ad esempio, l'applicazione elabora grandi quantità di dati utilizzando una logica complessa, e li restituisce sotto forma di tabella a cui gli utenti accedono spesso, è utile evitare di ricreare ogni volta la tabella. In modo analogo, se l'applicazione include una pagina che elabora dati complessi ma che viene aggiornata molto raramente, sarebbe poco efficace per il server ricreare quella pagina ad ogni richiesta.
Il meccanismo che ASP.NET ci mette a disposizione per facilitare il miglioramento delle prestazioni dell'applicazione in tali situazioni, è l’oggetto cache. ASP.NET supporta tre tipi di meccanismi di cache per le applicazioni web:
- Il Page Level Caching (chiamato anche Output Caching): questo meccanismo ci permette di salvare nella cache l’intero output dell’eleaborazione di una pagina e di riutilizzarlo ogni volta che ci sia una richiesta utente.
- Il Page Fragment Caching (altresì detto Partial-Page Output Caching): in cui a differenza del Page Level Caching, invece di contenere l’intero output della pagina si mantiene nella cache solo una parte della pagina (memorizzazione parziale).
- Il Data Caching: questo tipo di caching fornisce una serie di strumenti applicativi che permettono di specificare le condizioni, le quali una volta scadute il server deve rielaborare i dati memorizzati nella cache. Nel periodo di tempo che intercorre tra l’inserimento dei dati e la scadenza delle condizioni i dati sono ritenuti “validi” e pertanto possono essere utilizzati dallo sviluppatore risparmiando il tempo necessario ogni volta per la loro creazione.
Vediamo uno per uno i vari meccanismi di caching e come ci possono venire utili nella pratica.
Il Page Level Caching archivia nella memoria i contenuti dell’elaborazione della pagina ASP.NET. Questo meccanismo è comodo soprattutto per quelle pagine ASP.NET che raramente sono modificate ma che al contrario sono visualizzate di frequente. Infatti, in questo modo ASP.NET è in grado di inviare una risposta della pagina ad un client senza dover eseguire ogni volta l’intera elaborazione della pagina. L’implementazione del Page Level Caching può avvenire individualmente per ogni pagina usando la direttiva di pagina @OuputCache come segue:
<%@OutputCache Duration="60" VaryByParam="none" %>
oppure si possono creare i profili cache nel file Web.config, che consentono di definire una sola volta le impostazioni di memorizzazione nella cache e di utilizzare le stesse impostazioni per tutte le pagine del sito web. Come si può notare dall’esempio, la direttiva @OuputCache utilizza due parametri: Duration e VaryByParam.
Duration indica il tempo in secondi per cui l’output HTML dell’elaborazione della pagina ASP.NET viene mantenuta in memoria. Nel nostro esempio: Duration=60, significa che l’output viene mantenuto per 60 secondi, trascorsi i quali, la memoria viene liberata e la cache non risulta più disponibile alla successiva visita, quindi il server dovrà rielaborare la pagina ASP.NET ripopolando di nuovo la cache.
Il VaryByParam, indica il motivo per cui si deve forzatamente rielaborare la pagina anche se la Duration non è trascorsa del tutto; nel nostro esempio abbiamo impostato il paramento a none, ciò vuol dire che la pagina non verrà rielaborata mai se non dopo che saranno trascorsi 60 secondi (Duration=60). Oltre al valore none, questa proprietà può essere impostata anche su più parametri, in questi casi la cache di output conterrà una versione diversa del documento richiesto per ogni parametro specificato. I possibili valori oltre il "none" sono:
<%@OutputCache Duration="60" VaryByParam="*" %>
La pagina viene rielaborata prima dello scadere della Duration per qualsiasi nome di parametro di GET (passato tramite Querystring) o POST (passato tramite submit form)
<%@OutputCache Duration="60" VaryByParam="parametro1" %>
La pagina viene rielaborata prima dello scadere della Duration solo se varia il contenuto del parametro (parametro1) di GET (se inviato tramite Querystring) o POST (se inviato tramite submit form)
<%@OutputCache Duration="60" VaryByParam=" parametro1; parametro2" %>
La pagina viene rielaborata prima dello scadere della Duration solo se se varia almeno uno dei contenuti dei parametri(parametro1, parametro2, ecc.) di GET (se inviati tramite Querystring) o POST (se inviati tramite submit form). L’uso del parametro VaryByParam ci permette di avere cache specifiche per differenti “modi di vedere” della stessa pagina ASP.NET, il cui contenuto varia a secondo dei valori dei parametri passati tramite i metodi GET o POST.
Quello appena visto è la memorizzazione completa in quanto consente di mantenere l'intero contenuto di una pagina in memoria e di utilizzarlo per soddisfare le richieste del client. Ora addentriamoci nella memorizzazione parziale della pagina nella cache che ci consente di memorizzare nella cache solo alcune parti della pagina mentre altre si mantengono dinamiche. Questo meccanismo è il Page Fragment Caching.
Il Page Fragment Caching si incontra più spesso del Page Level Caching in quanto è più comune avere solo alcuni contenuti della pagina statici che tutti i contenuti. Questo meccanismo consente di memorizzare nella cache alcune parti dell'output della pagina, includendo le informazioni in un controllo utente e contrassegnandolo come inseribile nella cache. In questo modo, è possibile memorizzare nella cache un contenuto specifico all'interno di una pagina, mentre la pagina nel suo insieme non viene memorizzata nella cache e viene quindi ricreata ogni volta. Ad esempio, se si crea una pagina in cui vengono visualizzati contenuti sostanzialmente dinamici, come, ad esempio, news in tempo reale, ma che include anche sezioni statiche come l’archivio delle notizie del giorno precedente o della settimana, è possibile inserire queste ultime sezioni statiche nei controlli utente e consentirne la memorizzazione nella cache.
Infine arriviamo all’ultimo sistema di cache ovvero il Data Caching, più flessibile, ma anche quello dove bisogna scrivere più codice per implementarlo. Tipicamente la scelta di quali oggetti memorizzare ricade su quella tipologia di oggetti la cui costruzione è costosa in termini di tempo e che, possibilmente, il loro stato non venga aggiornato frequentemente in modo da non renderli obsoleti troppo presto. Questo tipo di servizi è offerto dalla classe Cache. Questa classe ci permette di gestire delle istanze di classi generiche basandoci su una chiave di accesso associata all’oggetto nel momento in cui questo viene inserito nella cache. Oltre alle consuete operazioni di gestione degli oggetti (inserimento, ricerca e cancellazione), la classe ci fornisce anche gli indispensabili strumenti per impostare il ciclo di vita degli oggetti inseriti. Al momento dell’inserimento di un oggetto in cache è infatti possibile specificare, oltre all’oggetto stesso, anche una serie di parametri che ci permettono di regolarizzare la permanenza dello stesso all’interno della cache.
- key: Identifica la chiave dell'oggetto da tenere in cache.
- value: Il valore dell'oggetto da tenere in cache.
- dependencies: Identifica le dipendenze, se ne ha, dell'oggetto. Se non esistono dipendenze basterà settare il valore a null.
- absoluteExpiration: Il tempo assoluto in cui l’oggetto inserito non sarà più ritenuto valido e quindi eliminato dalla cache.
- slidingExpiration: Rappresenta un timeout di inattività. Se non si accede all’oggetto entro questo intervallo di tempo, viene considerato scaduto e rimosso dalla cache. Utile quando vogliamo salvare una ricerca per un periodo limitato di tempo o i dati di un prodotto in catalogo. Quando vogliamo attivare absoluteExpiration dobbiamo settare slidingExpiration con il valore: TimeSpan.Zero. Se, invece, ci interesserà attivare slidingExpiration dobbiamo settare il valore di absoluteExpiration a: DateTime.MaxValue .
- priority: Quando ASP.NET rileva una scarsità di memoria può cercare di guadagnarne un pò eliminando quegli oggetti non usati in cache, prima di rimuoverli, controllerà la priorità settata. Solitamente si setta una priorità alta per gli oggetti che prendono più tempo per essere ricostruiti.
I valori possibili sono:
- High: L'oggetto verrà rimosso per l'ultimo rispetto agli altri
- AboveNormal
- Normal
- BelowNormal
- Low: L'oggetto verrà rimosso per primo rispetto agli altri
- NotRemovable: L'oggetto non verrà rimosso
- onRemoveCallback: È un delegato che verrà chiamato nel momento in cui un oggetto viene rimosso dalla cache. Utile per notificare all'applicazione se un oggetto non è più disponibile.
Come si evince dai parametri riportati, anche se l’oggetto cache offre una interfaccia di programmazione semplificata, fornisce servizi importanti per la gestione ottimale di una cache tra cui la gestione della eventuale scarsità della memoria provvedendo automaticamente a una selezione degli oggetti da eliminare in funzione delle indicazioni fornite dallo sviluppatore. Per memorizzare un oggetto nella cache si usa la seguente sintassi:
Cache[key]=value;per esempio:Cache["nomeUtente"] = userName // nome Utente è la key e userName è il value
Mentre per leggere il valore memorizzato nella cache:
variabile=Cache[key];per esempio:userId = Cache["nomeUtente "] // nome Utente è la key il value viene associato alla variabile userId
Si possono anche usare i metodi Insert o Add per aggiungere oggetti alla cache. I metodi Add ed Insert operano nello stesso modo solo che il metodo Add ritorna un riferimento all’oggetto che si sta inserendo in cache:
Cache.Insert(key,value);
Cache.Add(key,value); (simile al metodo Insert ma ritorna un riferimento all’oggetto che si sta inserendo nella cache)
Esempio:
Cache.Insert(“nomeUtente”,username); // con il metodo insertCache.Add(“nomeUtente”,username); // con il metodo add
- Articolo precedente Script ASP.NET gratis download: video, foto, template, email
- Articolo successivo Creare siti web multilingua con le Master Page