Mise en cache de données au démarrage de l’application (VB)
par Scott Mitchell
Dans n’importe quelle application web, certaines données sont fréquemment utilisées et certaines données sont rarement utilisées. Nous pouvons améliorer les performances de notre application ASP.NET en chargeant à l’avance les données fréquemment utilisées, une technique appelée . Ce tutoriel présente une approche du chargement proactif, qui consiste à charger des données dans le cache au démarrage de l’application.
Introduction
Les deux didacticiels précédents ont examiné la mise en cache des données dans les couches Présentation et Mise en cache. Dans Mise en cache des données avec ObjectDataSource, nous avons examiné l’utilisation des fonctionnalités de mise en cache d’ObjectDataSource pour mettre en cache les données dans la couche de présentation. La mise en cache des données dans l’architecture a examiné la mise en cache dans une nouvelle couche de mise en cache distincte. Ces deux didacticiels utilisaient le chargement réactif lors de l’utilisation du cache de données. Avec le chargement réactif, chaque fois que les données sont demandées, le système vérifie d’abord si elles sont dans le cache. Si ce n’est pas le cas, il récupère les données de la source d’origine, telle que la base de données, puis les stocke dans le cache. L’avantage main du chargement réactif est sa facilité d’implémentation. L’un de ses inconvénients est ses performances inégales entre les requêtes. Imaginez une page qui utilise la couche de mise en cache du didacticiel précédent pour afficher des informations sur le produit. Lorsque cette page est visitée pour la première fois, ou pour la première fois après que les données mises en cache ont été supprimées en raison de contraintes de mémoire ou de l’expiration spécifiée ayant été atteinte, les données doivent être récupérées de la base de données. Par conséquent, ces demandes d’utilisateurs prendront plus de temps que les demandes des utilisateurs qui peuvent être traitées par le cache.
Le chargement proactif fournit une autre stratégie de gestion du cache qui facilite les performances entre les requêtes en chargeant les données mises en cache avant qu’elles ne s’avèrent nécessaires. En règle générale, le chargement proactif utilise un processus qui vérifie régulièrement ou est averti lorsqu’une mise à jour des données sous-jacentes a été effectuée. Ce processus met ensuite à jour le cache pour le garder à jour. Le chargement proactif est particulièrement utile si les données sous-jacentes proviennent d’une connexion de base de données lente, d’un service Web ou d’une autre source de données particulièrement lente. Toutefois, cette approche du chargement proactif est plus difficile à implémenter, car elle nécessite la création, la gestion et le déploiement d’un processus pour case activée pour les modifications et mettre à jour le cache.
Une autre version du chargement proactif, et le type que nous allons explorer dans ce tutoriel, est le chargement de données dans le cache au démarrage de l’application. Cette approche est particulièrement utile pour mettre en cache des données statiques, telles que les enregistrements dans les tables de recherche de base de données.
Notes
Pour un examen plus approfondi des différences entre le chargement proactif et le chargement réactif, ainsi que des listes de avantages, d’inconvénients et de recommandations d’implémentation, reportez-vous à la section Gestion du contenu d’un cache du Guide de l’architecture de mise en cache pour les applications .NET Framework.
Étape 1 : Déterminer les données à mettre en cache au démarrage de l’application
Les exemples de mise en cache utilisant le chargement réactif que nous avons examinés dans les deux didacticiels précédents fonctionnent bien avec des données qui peuvent changer régulièrement et ne prennent pas de temps exorbitant à générer. Mais si les données mises en cache ne changent jamais, l’expiration utilisée par le chargement réactif est superflue. De même, si la génération des données mises en cache prend beaucoup de temps, les utilisateurs dont les demandes trouvent le cache vide devront supporter une longue attente pendant la récupération des données sous-jacentes. Envisagez de mettre en cache des données statiques et des données qui prennent un temps exceptionnellement long à générer au démarrage de l’application.
Alors que les bases de données ont de nombreuses valeurs dynamiques, qui changent fréquemment, la plupart ont également une bonne quantité de données statiques. Par exemple, pratiquement tous les modèles de données ont une ou plusieurs colonnes qui contiennent une valeur particulière d’un ensemble fixe de choix. Une Patients
table de base de données peut avoir une PrimaryLanguage
colonne, dont l’ensemble de valeurs peut être anglais, espagnol, Français, russe, japonais, etc. Souvent, ces types de colonnes sont implémentés à l’aide de tables de recherche. Au lieu de stocker la chaîne en anglais ou Français dans la Patients
table, une deuxième table est créée qui contient généralement deux colonnes ( un identificateur unique et une description de chaîne ) avec un enregistrement pour chaque valeur possible. La PrimaryLanguage
colonne de la Patients
table stocke l’identificateur unique correspondant dans la table de choix. Dans la figure 1, la langue principale du patient John Doe est l’anglais, tandis que Ed Johnson est le russe.
Figure 1 : La Languages
table est une table de choix utilisée par la Patients
table
L’interface utilisateur permettant de modifier ou de créer un nouveau patient inclut une liste déroulante de langues autorisées remplie par les enregistrements de la Languages
table. Sans mise en cache, chaque fois que cette interface est visitée, le système doit interroger la Languages
table. Cela est inutile et inutile, car les valeurs des tables de choix changent très rarement, voire jamais.
Nous pourrions mettre en cache les données à l’aide Languages
des mêmes techniques de chargement réactif examinées dans les didacticiels précédents. Toutefois, le chargement réactif utilise une expiration basée sur le temps, qui n’est pas nécessaire pour les données de table de recherche statiques. Bien que la mise en cache à l’aide du chargement réactif soit préférable à l’absence de mise en cache du tout, la meilleure approche consiste à charger de manière proactive les données de la table de recherche dans le cache au démarrage de l’application.
Dans ce tutoriel, nous allons voir comment mettre en cache des données de table de recherche et d’autres informations statiques.
Étape 2 : Examen des différentes façons de mettre en cache les données
Les informations peuvent être mises en cache par programmation dans une application ASP.NET à l’aide de diverses approches. Nous avons déjà vu comment utiliser le cache de données dans les tutoriels précédents. Vous pouvez également mettre en cache des objets par programmation à l’aide de membres statiques ou de l’état de l’application.
Lors de l’utilisation d’une classe, la classe doit généralement être instanciée avant que ses membres soient accessibles. Par exemple, pour appeler une méthode à partir de l’une des classes de notre couche de logique métier, nous devons d’abord créer une instance de la classe :
Dim productsAPI As New ProductsBLL()
productsAPI.SomeMethod()
productsAPI.SomeProperty = "Hello, World!"
Avant de pouvoir appeler SomeMethod ou travailler avec SomeProperty, nous devons d’abord créer un instance de la classe à l’aide de la New
mot clé. SomeMethod et SomeProperty sont associés à un instance particulier. La durée de vie de ces membres est liée à la durée de vie de leur objet associé. Les membres statiques, en revanche, sont des variables, des propriétés et des méthodes qui sont partagées entre toutes les instances de la classe et, par conséquent, ont une durée de vie aussi longue que la classe . Les membres statiques sont indiqués par le mot clé Shared
.
En plus des membres statiques, les données peuvent être mises en cache à l’aide de l’état de l’application. Chaque application ASP.NET gère une collection de noms/valeurs partagée entre tous les utilisateurs et les pages de l’application. Cette collection est accessible à l’aide de la HttpContext
propriété class s Application
et utilisée à partir d’une ASP.NET classe code-behind de page, comme suit :
Application("key") = value
Dim value As Object = Application("key")
Le cache de données fournit une API beaucoup plus riche pour la mise en cache des données, en fournissant des mécanismes pour les expirations basées sur le temps et les dépendances, les priorités des éléments de cache, etc. Avec les membres statiques et l’état de l’application, ces fonctionnalités doivent être ajoutées manuellement par le développeur de la page. Toutefois, lors de la mise en cache des données au démarrage de l’application pendant la durée de vie de l’application, les avantages du cache de données sont sans appel. Dans ce tutoriel, nous allons examiner le code qui utilise les trois techniques pour mettre en cache des données statiques.
Étape 3 : Mise en cache des données de tableSuppliers
Les tables de base de données Northwind que nous avons implémentées à ce jour n’incluent aucune table de recherche traditionnelle. Les quatre DataTables implémentées dans notre DAL sont toutes les tables de modèles dont les valeurs sont non statiques. Au lieu de passer du temps à ajouter un nouveau DataTable au DAL, puis une nouvelle classe et de nouvelles méthodes au BLL, pour ce tutoriel, nous allons simplement prétendre que les données de la Suppliers
table sont statiques. Par conséquent, nous pouvons mettre en cache ces données au démarrage de l’application.
Pour commencer, créez une classe nommée StaticCache.cs
dans le CL
dossier .
Figure 2 : Créer la StaticCache.vb
classe dans le CL
dossier
Nous devons ajouter une méthode qui charge les données au démarrage dans le magasin de cache approprié, ainsi que des méthodes qui retournent des données à partir de ce 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
Le code ci-dessus utilise une variable membre statique, suppliers
, pour contenir les résultats de la méthode s GetSuppliers()
de la SuppliersBLL
classe, qui est appelée à partir de la LoadStaticCache()
méthode . La LoadStaticCache()
méthode est destinée à être appelée au démarrage de l’application. Une fois ces données chargées au démarrage de l’application, toute page devant utiliser les données du fournisseur peut appeler la méthode de classe StaticCache
s GetSuppliers()
. Par conséquent, l’appel à la base de données pour obtenir les fournisseurs ne se produit qu’une seule fois, au démarrage de l’application.
Au lieu d’utiliser une variable membre statique comme magasin de cache, nous pourrions également utiliser l’état de l’application ou le cache de données. Le code suivant montre la classe réorganisée pour utiliser l’état de l’application :
<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
Dans LoadStaticCache()
, les informations du fournisseur sont stockées dans la clé de variable d’application. Il est retourné en tant que type approprié (Northwind.SuppliersDataTable
) à partir de GetSuppliers()
. Bien que l’état de l’application soit accessible dans les classes code-behind de ASP.NET pages à l’aide Application("key")
de , dans l’architecture, nous devons utiliser HttpContext.Current.Application("key")
pour obtenir le actuel HttpContext
.
De même, le cache de données peut être utilisé comme magasin de cache, comme le montre le code suivant :
<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
Pour ajouter un élément au cache de données sans expiration temporelle, utilisez les System.Web.Caching.Cache.NoAbsoluteExpiration
valeurs et System.Web.Caching.Cache.NoSlidingExpiration
comme paramètres d’entrée. Cette surcharge particulière de la méthode s du cache de Insert
données a été sélectionnée afin que nous puissions spécifier la priorité de l’élément de cache. La priorité est utilisée pour déterminer les éléments à extraire du cache lorsque la mémoire disponible est faible. Ici, nous utilisons la priorité NotRemovable
, qui garantit que cet élément de cache ne sera pas supprimé.
Notes
Ce téléchargement de ce tutoriel implémente la classe à l’aide StaticCache
de l’approche de variable membre statique. Le code de l’état de l’application et des techniques de cache de données est disponible dans les commentaires du fichier de classe.
Étape 4 : Exécution du code au démarrage de l’application
Pour exécuter du code lorsqu’une application web démarre pour la première fois, nous devons créer un fichier spécial nommé Global.asax
. Ce fichier peut contenir des gestionnaires d’événements pour les événements au niveau de l’application, de la session et de la requête, et c’est ici que nous pouvons ajouter du code qui sera exécuté chaque fois que l’application démarre.
Ajoutez le Global.asax
fichier au répertoire racine de votre application web en cliquant avec le bouton droit sur le nom du projet de site web dans le Explorateur de solutions de Visual Studio et en choisissant Ajouter un nouvel élément. Dans la boîte de dialogue Ajouter un nouvel élément, sélectionnez le type d’élément Classe d’application globale, puis cliquez sur le bouton Ajouter.
Notes
Si vous avez déjà un Global.asax
fichier dans votre projet, le type d’élément De classe d’application globale n’est pas répertorié dans la boîte de dialogue Ajouter un nouvel élément.
Figure 3 : Ajouter le Global.asax
fichier au répertoire racine de votre application web (cliquer pour afficher l’image en taille réelle)
Le modèle de fichier par défaut Global.asax
comprend cinq méthodes dans une balise côté <script>
serveur :
Application_Start
s’exécute lorsque l’application web démarre pour la première foisApplication_End
s’exécute lorsque l’application s’arrêteApplication_Error
s’exécute chaque fois qu’une exception non gérée atteint l’applicationSession_Start
s’exécute lors de la création d’une sessionSession_End
s’exécute lorsqu’une session a expiré ou est abandonnée
Le Application_Start
gestionnaire d’événements n’est appelé qu’une seule fois pendant le cycle de vie d’une application. L’application démarre la première fois qu’une ressource ASP.NET est demandée à l’application et continue à s’exécuter jusqu’à ce que l’application soit redémarrée, ce qui peut se produire en modifiant le contenu du /Bin
dossier, en Global.asax
modifiant le contenu du App_Code
dossier ou en modifiant le Web.config
fichier, entre autres causes. Reportez-vous à ASP.NET Vue d’ensemble du cycle de vie des applications pour une discussion plus détaillée sur le cycle de vie de l’application.
Pour ces tutoriels, nous avons uniquement besoin d’ajouter du code à la Application_Start
méthode. N’hésitez donc pas à supprimer les autres. Dans Application_Start
, appelez simplement la StaticCache
méthode de classe s LoadStaticCache()
, qui charge et met en cache les informations du fournisseur :
<%@ Application Language="VB" %>
<script runat="server">
Sub Application_Start(ByVal sender As Object, ByVal e As EventArgs)
StaticCache.LoadStaticCache()
End Sub
</script>
C’est tout ce qu’il y a à ça ! Au démarrage de l’application, la LoadStaticCache()
méthode récupère les informations du fournisseur à partir de la BLL et les stocke dans une variable membre statique (ou tout magasin de cache que vous avez utilisé dans la StaticCache
classe). Pour vérifier ce comportement, définissez un point d’arrêt dans la Application_Start
méthode et exécutez votre application. Notez que le point d’arrêt est atteint au démarrage de l’application. Toutefois, les requêtes suivantes n’entraînent pas l’exécution de la Application_Start
méthode.
Figure 4 : Utiliser un point d’arrêt pour vérifier que le Application_Start
gestionnaire d’événements est en cours d’exécution (cliquez pour afficher l’image de taille réelle)
Notes
Si vous n’atteignez pas le Application_Start
point d’arrêt lorsque vous démarrez le débogage pour la première fois, c’est parce que votre application a déjà démarré. Forcez l’application à redémarrer en modifiant vos Global.asax
fichiers ou Web.config
, puis réessayez. Vous pouvez simplement ajouter (ou supprimer) une ligne vide à la fin de l’un de ces fichiers pour redémarrer rapidement l’application.
Étape 5 : affichage des données mises en cache
À ce stade, la StaticCache
classe a une version des données du fournisseur mises en cache au démarrage de l’application et accessible via sa GetSuppliers()
méthode. Pour utiliser ces données à partir de la couche de présentation, nous pouvons utiliser un ObjetDataSource ou appeler par programmation la méthode s de classe StaticCache
à GetSuppliers()
partir d’une classe code-behind de ASP.NET page. Examinons l’utilisation des contrôles ObjectDataSource et GridView pour afficher les informations du fournisseur mises en cache.
Commencez par ouvrir la AtApplicationStartup.aspx
page dans le Caching
dossier. Faites glisser un GridView de la boîte à outils vers le concepteur, affectant à sa ID
propriété la valeur Suppliers
. Ensuite, à partir de la balise active GridView, choisissez de créer un ObjetDataSource nommé SuppliersCachedDataSource
. Configurez ObjectDataSource pour utiliser la StaticCache
méthode de classe s GetSuppliers()
.
Figure 5 : Configurer ObjectDataSource pour utiliser la StaticCache
classe (cliquer pour afficher l’image en taille réelle)
Figure 6 : Utiliser la GetSuppliers()
méthode pour récupérer les données de fournisseur mises en cache (cliquer pour afficher l’image en taille réelle)
Une fois l’Assistant terminé, Visual Studio ajoute automatiquement BoundFields pour chacun des champs de données dans SuppliersDataTable
. Votre balisage déclaratif GridView et ObjectDataSource doit ressembler à ce qui suit :
<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 figure 7 montre la page lorsqu’elle est consultée via un navigateur. La sortie est identique si nous avons extrait les données de la classe S SuppliersBLL
BLL, mais l’utilisation de la StaticCache
classe retourne les données du fournisseur telles qu’elles sont mises en cache au démarrage de l’application. Vous pouvez définir des points d’arrêt dans la StaticCache
méthode de classe s GetSuppliers()
pour vérifier ce comportement.
Figure 7 : Les données du fournisseur mises en cache sont affichées dans un GridView (cliquer pour afficher une image en taille réelle)
Résumé
La plupart des modèles de données contiennent une bonne quantité de données statiques, généralement implémentées sous la forme de tables de recherche. Étant donné que ces informations sont statiques, il n’y a aucune raison d’accéder en permanence à la base de données chaque fois que ces informations doivent être affichées. En outre, en raison de leur nature statique, lors de la mise en cache des données, il n’est pas nécessaire d’expirer. Dans ce tutoriel, nous avons vu comment prendre ces données et les mettre en cache dans le cache de données, l’état de l’application et via une variable membre statique. Ces informations sont mises en cache au démarrage de l’application et restent dans le cache pendant toute la durée de vie de l’application.
Dans ce tutoriel et les deux derniers, nous avons examiné la mise en cache des données pour la durée de vie de l’application, ainsi que l’utilisation d’expirations basées sur le temps. Toutefois, lors de la mise en cache des données de base de données, une expiration basée sur le temps peut être inférieure à l’idéal. Plutôt que de vider régulièrement le cache, il serait préférable de ne supprimer l’élément mis en cache que lorsque les données de base de données sous-jacentes sont modifiées. Cet idéal est possible grâce à l’utilisation de dépendances de cache SQL, que nous examinerons dans notre prochain tutoriel.
Bonne programmation !
À propos de l’auteur
Scott Mitchell, auteur de sept livres ASP/ASP.NET et fondateur de 4GuysFromRolla.com, travaille avec les technologies Web Microsoft depuis 1998. Scott travaille comme consultant indépendant, formateur et écrivain. Son dernier livre est Sams Teach Yourself ASP.NET 2.0 in 24 Heures. Il est accessible à l’adressemitchell@4GuysFromRolla.com . ou via son blog, qui peut être trouvé à l’adresse http://ScottOnWriting.NET.
Un merci spécial à
Cette série de tutoriels a été examinée par de nombreux réviseurs utiles. Les réviseurs principaux de ce tutoriel étaient Teresa Murphy et Zack Jones. Vous souhaitez consulter mes prochains articles MSDN ? Si c’est le cas, déposez-moi une ligne à mitchell@4GuysFromRolla.com.