4 votes

Mise en cache asynchrone en ASP.NET

Tout d'abord, je pense que je devrais faire un lien vers cet article ce qui accomplit à peu près ce que je veux.

Voici mon problème : J'ai un contrôle utilisateur sur mon site qui a besoin de mettre en cache certaines données pendant au moins 15 minutes, puis de les extraire à nouveau de la base de données. Le problème est que l'extraction prend environ 7-10 secondes pour extraire le résultat de la base de données.

Je pense que je peux fixer la durée du cache à deux heures, puis avoir une propriété dans l'objet mis en cache pour indiquer quand l'objet a été chargé (appelons cela la propriété LoadDate). Le code pourrait alors extraire l'objet mis en cache.

  • S'il est nul, je n'ai pas d'autre choix que d'extraire les données de manière synchrone et de charger ensuite mon contrôle utilisateur.
  • S'il n'est pas nul, je veux aller de l'avant et charger les données sur mon contrôle utilisateur à partir de l'objet mis en cache. Je vérifierais ensuite la propriété LoadDate. Si cela fait 15 minutes ou plus, il faut mettre en place un processus asynchrone pour recharger le cache.
    • Il doit y avoir un processus pour verrouiller l'objet de cache pendant la mise à jour.
    • J'ai besoin d'une instruction if qui dise que si l'objet est verrouillé, il faut oublier de le mettre à jour. Cela s'appliquerait aux chargements de pages ultérieurs par d'autres utilisateurs, car le premier utilisateur mettrait déjà à jour le cache et je ne veux pas mettre à jour le cache encore et encore ; il devrait juste être mis à jour par le premier appel. N'oubliez pas que je charge déjà mon contrôle utilisateur avant même de procéder à la vérification du cache.

Dans l'article dont j'ai donné le lien précédemment, la réponse configure parfaitement la mise à jour du cache, mais je ne crois pas qu'elle soit asynchrone. La question commençait par le faire de manière asynchrone en utilisant Page.RegisterAsyncTask. [Question 1] Je n'arrive pas à trouver d'informations sur le fait que cela permettrait à un processus asynchrone de continuer même si l'utilisateur a quitté la page ?

[Question 2] Quelqu'un a-t-il une bonne idée de la façon de procéder ? J'ai un peu de code, mais il est devenu extrêmement long et ne semble toujours pas fonctionner correctement.

4voto

mikemanne Points 2399

Question 1 (RegisterAsyncTask)

Une chose très importante à retenir : du point de vue du client/de l'utilisateur/du navigateur, cela ne rend PAS la demande asynchrone. Si la tâche que vous enregistrez prend 30 secondes pour se terminer, le navigateur attendra toujours pendant plus de 30 secondes. La seule chose que RegisterAsyncTask fait, c'est de libérer votre fil de travail vers IIS pour la durée de l'appel asynchrone. Ne vous méprenez pas, c'est toujours une technique précieuse et importante. Cependant, pour l'utilisateur/navigateur qui effectue cette requête particulière, elle n'a pas d'impact notable sur le temps de réponse.

Question 2

Ce n'est peut-être pas la meilleure solution à votre problème, mais c'est quelque chose que j'ai utilisé dans le passé et qui pourrait vous aider : lorsque vous ajouter votre article au cache spécifier une expiration absolue et un retour d'appel onRemoveCallback. Créez une fonction qui récupère les données fraîches et les met dans le cache : c'est la fonction que vous devez passer comme onRemoveCallback. De cette façon, chaque fois que vos données mises en cache expirent, un rappel se produit pour remettre des données fraîches dans le cache. Comme le rappel se produit à la suite d'un événement d'expiration du cache, il n'y a pas de demande de l'utilisateur qui attende les 7 à 10 secondes nécessaires pour mettre en cache des données fraîches.

Ce n'est pas une conception parfaite. Quelques mises en garde :

  • Comment charger le cache au départ ? Le plus simple est d'appeler votre fonction de chargement du cache à partir de la fonction Application_Start.
  • Toutes les 15 minutes, il y aura une fenêtre de 7 à 10 secondes où le cache sera vide. Toutes les requêtes effectuées pendant cette période devront aller chercher les données elles-mêmes. En fonction des habitudes d'utilisation de votre système, cette petite fenêtre peut être acceptable, et seules quelques demandes se produiront pendant cette période.
  • Il n'est pas garanti que le rappel du cache se produise précisément lorsque l'élément mis en cache expire. Si le système est extrêmement chargé, il peut y avoir un délai avant que le rappel ne soit déclenché et que le cache ne soit rechargé. Encore une fois, en fonction de l'utilisation de votre système, cela peut être un problème mineur ou important.

Je suis désolé de ne pas avoir de réponse infaillible pour vous (je vais garder un œil sur ce fil de discussion - peut-être qu'une autre SO'er en aura une !) Mais comme je l'ai dit, j'ai utilisé cette approche avec un certain succès, et à moins que votre système soit extrêmement chargé, cela devrait aider à répondre à la question.

Edit : Une légère modification de l'approche ci-dessus, basée sur le commentaire du PO.

Vous pourriez mettre en cache une valeur fictive et l'utiliser uniquement pour déclencher votre fonction de rafraîchissement des données (refreshCachedData). Ce n'est pas particulièrement élégant, mais je l'ai déjà fait :)

Pour élaborer : gardez vos données réelles en cache dans le cache avec une clé "MyData", sans expiration et sans onRemoveCallback. Chaque fois que vous mettez en cache des données fraîches dans "MyData", vous ajoutez également une valeur fictive à votre cache : "MyDataRebuildTrigger", avec une expiration de 15 minutes, et avec un onRemoveCallback qui reconstruit vos données réelles mises en cache. Ainsi, il n'y a pas d'intervalle de 7 à 10 secondes lorsque "MesDonnées" est vide.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X