Nota
L'accesso a questa pagina richiede l'autorizzazione. È possibile provare ad accedere o modificare le directory.
L'accesso a questa pagina richiede l'autorizzazione. È possibile provare a modificare le directory.
In qualsiasi applicazione Web alcuni dati verranno usati di frequente e alcuni dati verranno usati raramente. È possibile migliorare le prestazioni dell'applicazione ASP.NET caricando in anticipo i dati usati di frequente, una tecnica nota come . Questa esercitazione illustra un approccio al caricamento proattivo, che consiste nel caricare i dati nella cache all'avvio dell'applicazione.
Introduzione
Le due esercitazioni precedenti hanno esaminato la memorizzazione nella cache dei dati nei livelli di presentazione e di caching. In Memorizzazione nella cache dei dati con ObjectDataSource è stato esaminato l'uso delle funzionalità di memorizzazione nella cache di ObjectDataSource per memorizzare nella cache i dati nel livello presentazione. Memorizzazione nella cache dei dati nell'architettura, esaminata in un nuovo livello di caching separato. Entrambe queste esercitazioni usano il caricamento reattivo nell'uso della cache dei dati. Con il caricamento reattivo, ogni volta che vengono richiesti i dati, il sistema controlla innanzitutto se si trova nella cache. In caso contrario, recupera i dati dall'origine di origine, ad esempio il database, e li archivia nella cache. Il vantaggio principale del caricamento reattivo è la sua facilità di implementazione. Uno dei suoi svantaggi è rappresentato da prestazioni non uniformi tra le richieste. Immagina una pagina che utilizza il livello di memorizzazione nella cache dell'esercitazione precedente per visualizzare le informazioni sul prodotto. Quando questa pagina viene visitata per la prima volta o visitata per la prima volta dopo che i dati memorizzati nella cache sono stati rimossi a causa di vincoli di memoria o della scadenza specificata, i dati devono essere recuperati dal database. Pertanto, queste richieste di utenti richiederanno più tempo rispetto alle richieste degli utenti che possono essere gestite dalla cache.
Il caricamento proattivo offre una strategia di gestione della cache alternativa che semplifica le prestazioni tra le richieste caricando i dati memorizzati nella cache prima che siano necessari. In genere, il caricamento proattivo usa un processo che controlla periodicamente o riceve una notifica quando è stato eseguito un aggiornamento ai dati sottostanti. Questo processo aggiorna quindi la cache per mantenerla aggiornata. Il caricamento proattivo è particolarmente utile se i dati sottostanti provengono da una connessione di database lenta, da un servizio Web o da un'altra origine dati particolarmente lenta. Tuttavia, questo approccio al caricamento proattivo è più difficile da implementare, perché richiede la creazione, la gestione e la distribuzione di un processo per verificare la presenza di modifiche e aggiornare la cache.
Un altro tipo di caricamento proattivo e il tipo che verrà esplorato in questa esercitazione consiste nel caricare i dati nella cache all'avvio dell'applicazione. Questo approccio è particolarmente utile per la memorizzazione nella cache dei dati statici, ad esempio i record nelle tabelle di ricerca del database.
Annotazioni
Per un'analisi più approfondita delle differenze tra caricamento proattivo e reattivo, nonché elenchi di pro, svantaggi e consigli sull'implementazione, vedere la sezione Gestione del contenuto di una cache della Guida all'architettura di memorizzazione nella cache per le applicazioni .NET Framework.
Passaggio 1: Determinazione dei dati da memorizzare nella cache all'avvio dell'applicazione
Gli esempi di memorizzazione nella cache che usano il caricamento reattivo esaminato nelle due esercitazioni precedenti funzionano bene con i dati che possono cambiare periodicamente e non richiedono molto tempo per generare. Tuttavia, se i dati memorizzati nella cache non cambiano mai, la scadenza usata dal caricamento reattivo è superflua. Analogamente, se i dati memorizzati nella cache richiedono molto tempo per la generazione, gli utenti le cui richieste trovano la cache vuota dovranno sopportare una lunga attesa mentre vengono recuperati i dati sottostanti. Prendere in considerazione la memorizzazione nella cache dei dati statici e dei dati che richiedono tempi estremamente lunghi per la generazione all'avvio dell'applicazione.
Anche se i database hanno molti valori dinamici e a modifica frequente, la maggior parte ha anche una quantità equa di dati statici. Ad esempio, praticamente tutti i modelli di dati hanno una o più colonne che contengono un determinato valore da un set fisso di scelte. Una Patients tabella di database potrebbe avere una PrimaryLanguage colonna, il cui set di valori potrebbe essere inglese, spagnolo, francese, russo, giapponese e così via. Spesso, questi tipi di colonne vengono implementati usando le tabelle di ricerca. Anziché archiviare la stringa inglese o francese nella Patients tabella, viene creata una seconda tabella con, in genere, due colonne, un identificatore univoco e una descrizione stringa, con un record per ogni valore possibile. La PrimaryLanguage colonna nella Patients tabella archivia l'identificatore univoco corrispondente nella tabella di ricerca. Nella figura 1, la lingua primaria del paziente John Doe è inglese, mentre Ed Johnson è russo.
Figura 1: La Languages tabella è una tabella di ricerca usata dalla Patients tabella
L'interfaccia utente per la modifica o la creazione di un nuovo paziente include un elenco a discesa di lingue consentite popolate dai record nella Languages tabella. Senza memorizzazione nella cache, ogni volta che questa interfaccia viene visitata, il sistema deve eseguire query sulla Languages tabella. Ciò è sprecato e non necessario perché i valori della tabella di ricerca cambiano molto raramente, se mai.
È possibile memorizzare nella cache i Languages dati usando le stesse tecniche di caricamento reattive esaminate nelle esercitazioni precedenti. Il caricamento reattivo, tuttavia, usa una scadenza basata sul tempo, che non è necessaria per i dati della tabella di ricerca statica. Anche se la memorizzazione nella cache tramite caricamento reattivo sarebbe preferibile rispetto a nessuna memorizzazione nella cache, l'approccio migliore consiste nel caricare in modo proattivo i dati della tabella di ricerca nella cache all'avvio dell'applicazione.
In questa esercitazione verrà illustrato come memorizzare nella cache i dati della tabella di ricerca e altre informazioni statiche.
Passaggio 2: Esame dei diversi modi per memorizzare nella cache i dati
Le informazioni possono essere memorizzate nella cache a livello di codice in un'applicazione ASP.NET usando un'ampia gamma di approcci. Abbiamo già visto come usare la cache dei dati nelle esercitazioni precedenti. In alternativa, gli oggetti possono essere memorizzati nella cache a livello di codice usando membri statici o lo stato dell'applicazione.
Quando si lavora con una classe, è generalmente necessario prima istanziarla per accedere ai suoi membri. Ad esempio, per richiamare un metodo da una delle classi nel livello della logica di business, è prima necessario creare un'istanza della classe :
Dim productsAPI As New ProductsBLL()
productsAPI.SomeMethod()
productsAPI.SomeProperty = "Hello, World!"
Prima di poter richiamare SomeMethod o lavorare con SomeProperty, è prima necessario creare un'istanza della classe usando la New parola chiave .
SomeMethod e SomeProperty sono associati a un'istanza specifica. La durata di questi membri è associata alla durata dell'oggetto associato.
I membri statici, d'altra parte, sono variabili, proprietà e metodi condivisi tra tutte le istanze della classe e, di conseguenza, hanno una durata fino a quando la classe. I membri statici sono indicati dalla parola chiave Shared.
Oltre ai membri statici, i dati possono essere memorizzati nella cache usando lo stato dell'applicazione. Ogni applicazione ASP.NET gestisce una raccolta nome/valore condivisa tra tutti gli utenti e le pagine dell'applicazione. È possibile accedere a questa raccolta utilizzando la classe HttpContext s proprietà Application, e utilizzata da una classe code-behind di una pagina ASP.NET, come illustrato di seguito:
Application("key") = value
Dim value As Object = Application("key")
La cache dei dati offre un'API molto più completa per la memorizzazione dei dati nella cache, fornendo meccanismi per le scadenze basate su tempo e dipendenze, priorità degli elementi della cache e così via. Con i membri statici e lo stato dell'applicazione, tali funzionalità devono essere aggiunte manualmente dallo sviluppatore della pagina. Quando i dati vengono memorizzati nella cache all'avvio per l'intera durata dell'applicazione, tuttavia, i vantaggi della cache dei dati diventano irrilevanti. In questa esercitazione verrà esaminato il codice che usa tutte e tre le tecniche per la memorizzazione nella cache dei dati statici.
Passaggio 3: Memorizzazione nella cache dei dati dellaSupplierstabella
Le tabelle di database Northwind implementate finora non includono tabelle di ricerca tradizionali. Le quattro DataTable implementate nel nostro DAL modellano tutte tabelle i cui valori non sono statici. Invece di dedicare il tempo necessario per aggiungere una nuova tabella DataTable a DAL e quindi a una nuova classe e metodi al BLL, per questa esercitazione si fa semplicemente finta che i dati della Suppliers tabella siano statici. Di conseguenza, è possibile memorizzare questi dati nella cache all'avvio dell'applicazione.
Per iniziare, creare una nuova classe denominata StaticCache.cs nella CL cartella .
Figura 2: Creare la StaticCache.vb classe nella CL cartella
È necessario aggiungere un metodo che carica i dati all'avvio nell'archivio cache appropriato, nonché metodi che restituiscono dati da questa cache.
<System.ComponentModel.DataObject()> _
Public Class StaticCache
Private Shared suppliers As Northwind.SuppliersDataTable = Nothing
Public Shared Sub LoadStaticCache()
' Get suppliers - cache using a static member variable
Dim suppliersBLL As New SuppliersBLL()
suppliers = suppliersBLL.GetSuppliers()
End Sub
<DataObjectMethodAttribute(DataObjectMethodType.Select, True)> _
Public Shared Function GetSuppliers() As Northwind.SuppliersDataTable
Return suppliers
End Function
End Class
Il codice precedente utilizza una variabile membro statica, suppliers, per contenere i risultati del metodo SuppliersBLL della classe GetSuppliers(), che viene chiamato dal metodo LoadStaticCache(). Il LoadStaticCache() metodo deve essere chiamato durante l'avvio dell'applicazione. Dopo che questi dati sono stati caricati all'avvio dell'applicazione, qualsiasi pagina che deve usare i dati del fornitore può chiamare il StaticCache metodo della GetSuppliers() classe . Pertanto, la chiamata al database per ottenere i fornitori avviene una sola volta, all'avvio dell'applicazione.
Anziché usare una variabile membro statica come archivio cache, è possibile usare in alternativa lo stato dell'applicazione o la cache dei dati. Il codice seguente mostra la classe modificata per usare lo stato dell'applicazione.
<System.ComponentModel.DataObject()> _
Public Class StaticCache
Public Shared Sub LoadStaticCache()
' Get suppliers - cache using application state
Dim suppliersBLL As New SuppliersBLL()
HttpContext.Current.Application("key") = suppliers
End Sub
<DataObjectMethodAttribute(DataObjectMethodType.Select, True)> _
Public Shared Function GetSuppliers() As Northwind.SuppliersDataTable
Return TryCast(HttpContext.Current.Application("key"), _
Northwind.SuppliersDataTable)
End Function
End Class
In LoadStaticCache()le informazioni sul fornitore vengono archiviate nella chiave della variabile dell'applicazione. Viene restituito come tipo appropriato (Northwind.SuppliersDataTable) da GetSuppliers(). Anche se è possibile accedere allo stato dell'applicazione nel code-behind delle pagine ASP.NET usando Application("key"), nell'architettura è necessario usare HttpContext.Current.Application("key") per ottenere il HttpContext corrente.
Analogamente, la cache dei dati può essere usata come archivio cache, come illustrato nel codice seguente:
<System.ComponentModel.DataObject()> _
Public Class StaticCache
Public Shared Sub LoadStaticCache()
' Get suppliers - cache using a static member variable
Dim suppliersBLL As New SuppliersBLL()
HttpRuntime.Cache.Insert("key", suppliers, Nothing, _
Cache.NoAbsoluteExpiration, Cache.NoSlidingExpiration, _
CacheItemPriority.NotRemovable, Nothing)
End Sub
<System.ComponentModel.DataObjectMethodAttribute_
(System.ComponentModel.DataObjectMethodType.Select, True)> _
Public Shared Function GetSuppliers() As Northwind.SuppliersDataTable
Return TryCast(HttpRuntime.Cache("key"), Northwind.SuppliersDataTable)
End Function
End Class
Per aggiungere un elemento alla cache dei dati senza scadenza basata sul tempo, usare i System.Web.Caching.Cache.NoAbsoluteExpiration valori e System.Web.Caching.Cache.NoSlidingExpiration come parametri di input. Questo particolare overload del metodo della cache dei dati è stato scelto per poter specificare la Insert dell'elemento nella cache. La priorità viene usata per determinare gli elementi da scavengere dalla cache quando la memoria disponibile è insufficiente. Qui usiamo la priorità NotRemovable, che garantisce che questo elemento della cache non venga eliminato.
Annotazioni
Il download di questo tutorial implementa la classe StaticCache usando l'approccio alla variabile membro statico. Il codice per le tecniche relative allo stato dell'applicazione e alla cache dei dati è disponibile nei commenti nel file di classe.
Passaggio 4: Esecuzione del codice all'avvio dell'applicazione
Per eseguire il codice all'avvio di un'applicazione Web, è necessario creare un file speciale denominato Global.asax. Questo file può contenere gestori eventi per eventi a livello di applicazione, sessione e richiesta ed è qui che è possibile aggiungere codice che verrà eseguito ogni volta che viene avviata l'applicazione.
Aggiungere il Global.asax file alla directory radice dell'applicazione Web facendo clic con il pulsante destro del mouse sul nome del progetto del sito Web in Esplora soluzioni di Visual Studio e scegliendo Aggiungi nuovo elemento. Nella finestra di dialogo Aggiungi nuovo elemento selezionare il tipo di elemento Classe applicazione globale e quindi fare clic sul pulsante Aggiungi.
Annotazioni
Se nel progetto è già presente un Global.asax file, il tipo di elemento Classe applicazione globale non verrà elencato nella finestra di dialogo Aggiungi nuovo elemento.
Figura 3: Aggiungere il Global.asax file alla directory radice dell'applicazione Web (fare clic per visualizzare l'immagine a dimensione intera)
Il modello di file predefinito Global.asax include cinque metodi all'interno di un tag lato <script> server:
-
Application_Startviene eseguito all'avvio dell'applicazione Web per la prima volta -
Application_Endviene eseguito quando l'applicazione si sta spegnendo -
Application_Errorviene eseguito ogni volta che un'eccezione non gestita raggiunge l'applicazione -
Session_Startviene eseguito quando viene creata una nuova sessione -
Session_Endviene eseguito quando una sessione è scaduta o abbandonata
Il Application_Start gestore eventi viene chiamato una sola volta durante il ciclo di vita di un'applicazione. L'applicazione avvia la prima volta che viene richiesta una risorsa ASP.NET dall'applicazione e continua a essere eseguita fino al riavvio dell'applicazione, che può verificarsi modificando il contenuto della /Bin cartella, modificando Global.asax, modificando il contenuto nella App_Code cartella o modificando il Web.config file, tra le altre cause. Per una discussione più dettagliata sul ciclo di vita dell'applicazione, fare riferimento a ASP.NET Panoramica del ciclo di vita dell'applicazione.
Per queste esercitazioni è sufficiente aggiungere codice al Application_Start metodo, quindi è possibile rimuovere gli altri. In Application_Startè sufficiente chiamare il StaticCache metodo della LoadStaticCache() classe , che caricherà e memorizza nella cache le informazioni del fornitore:
<%@ Application Language="VB" %>
<script runat="server">
Sub Application_Start(ByVal sender As Object, ByVal e As EventArgs)
StaticCache.LoadStaticCache()
End Sub
</script>
È tutto qui! All'avvio dell'applicazione, il LoadStaticCache() metodo reperirà le informazioni sul fornitore dal BLL e lo archivierà in una variabile membro statica (o in qualsiasi archivio cache usato nella StaticCache classe ). Per verificare questo comportamento, impostare un punto di interruzione nel Application_Start metodo ed eseguire l'applicazione. Si noti che il punto di interruzione viene raggiunto all'avvio dell'applicazione. Le richieste successive, tuttavia, non causano l'esecuzione del Application_Start metodo.
Figura 4: Usare un punto di interruzione per verificare che il gestore eventi sia in esecuzione (Application_Start a dimensione intera)
Annotazioni
Se non si raggiunge il punto di interruzione al primo avvio del Application_Start debug, è perché l'applicazione è già stata avviata. Forzare il riavvio dell'applicazione modificando i Global.asax file o Web.config e quindi riprovare. È sufficiente aggiungere (o rimuovere) una riga vuota alla fine di uno di questi file per riavviare rapidamente l'applicazione.
Passaggio 5: Visualizzazione dei dati memorizzati nella cache
A questo punto la StaticCache classe ha una versione dei dati del fornitore memorizzati nella cache all'avvio dell'applicazione a cui è possibile accedere tramite il relativo GetSuppliers() metodo. Per usare questi dati dal livello presentazione, è possibile usare l'ObjectDataSource o richiamare programmaticamente il metodo della classe StaticCache da una classe code-behind della pagina ASP.NET. Esaminare l'uso dei controlli ObjectDataSource e GridView per visualizzare le informazioni sul fornitore memorizzate nella cache.
Per iniziare, aprire la AtApplicationStartup.aspx pagina nella Caching cartella . Trascina un GridView dagli strumenti nel designer, impostandone la proprietà ID su Suppliers. Successivamente, dallo smart tag GridView, scegli di creare un nuovo ObjectDataSource denominato SuppliersCachedDataSource. Configurare ObjectDataSource per l'uso del StaticCache metodo della classe .GetSuppliers()
Figura 5: Configurare ObjectDataSource per l'uso della classe (StaticCache a dimensione intera)
Figura 6: Usare il GetSuppliers() metodo per recuperare i dati dei fornitori memorizzati nella cache (fare clic per visualizzare l'immagine a dimensione intera)
Dopo aver completato la procedura guidata, Visual Studio aggiungerà automaticamente BoundFields per ognuno dei campi dati in SuppliersDataTable. Il markup dichiarativo di GridView e ObjectDataSource dovrebbe essere simile al seguente:
<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" />
La figura 7 mostra la pagina quando viene visualizzata tramite un browser. L'output è uguale a quando sono stati estratti i dati dalla classe BLL, SuppliersBLL ma l'uso della StaticCache classe restituisce i dati del fornitore memorizzati nella cache all'avvio dell'applicazione. È possibile impostare punti di interruzione nella classe StaticCache nel metodo GetSuppliers() per verificare questo comportamento.
Figura 7: I dati dei fornitori memorizzati nella cache vengono visualizzati in un controllo GridView (fare clic per visualizzare un'immagine a dimensione intera)
Riassunto
La maggior parte di ogni modello di dati contiene una quantità equa di dati statici, in genere implementata sotto forma di tabelle di ricerca. Poiché queste informazioni sono statiche, non esiste alcun motivo per accedere continuamente al database ogni volta che queste informazioni devono essere visualizzate. Inoltre, a causa della sua natura statica, quando si memorizzano i dati nella cache non è necessaria una scadenza. In questa esercitazione è stato illustrato come accettare tali dati e memorizzarlo nella cache dei dati, nello stato dell'applicazione e tramite una variabile membro statica. Queste informazioni vengono memorizzate nella cache all'avvio dell'applicazione e rimangono nella cache per tutta la durata dell'applicazione.
In questa esercitazione e nelle ultime due, abbiamo esaminato sia la memorizzazione dei dati nella cache per la durata dell'applicazione, sia l'uso delle scadenze basate sul tempo. Quando si memorizzano nella cache i dati del database, tuttavia, una scadenza basata sul tempo può essere inferiore all'ideale. Anziché scaricare periodicamente la cache, sarebbe ottimale rimuovere solo l'elemento memorizzato nella cache quando i dati del database sottostanti vengono modificati. Questa soluzione ideale è possibile tramite l'uso delle dipendenze della cache SQL, che verranno esaminate nell'esercitazione successiva.
Buon programmatori!
Informazioni sull'autore
Scott Mitchell, autore di sette libri ASP/ASP.NET e fondatore di 4GuysFromRolla.com, ha lavorato con le tecnologie Web Microsoft dal 1998. Scott lavora come consulente indipendente, formatore e scrittore. Il suo ultimo libro è Sams Teach Yourself ASP.NET 2.0 in 24 ore. Può essere raggiunto a mitchell@4GuysFromRolla.com.
Grazie speciale a
Questa serie di esercitazioni è stata esaminata da molti revisori competenti. I revisori principali per questa esercitazione erano Teresa Murphy e Zack Jones. Si è interessati a esaminare i prossimi articoli MSDN? In tal caso, mandami un messaggio a mitchell@4GuysFromRolla.com.