Utiliser 'HttpContext.Current.Cache' en toute sécurité
Je suis en utilisant Cache
dans une méthode de service web comme ceci:
var pblDataList = (List<blabla>)HttpContext.Current.Cache.Get("pblDataList");
if (pblDataList == null)
{
var PBLData = dc.ExecuteQuery<blabla>(@"SELECT blabla");
pblDataList = PBLData.ToList();
HttpContext.Current.Cache.Add("pblDataList", pblDataList, null,
DateTime.Now.Add(new TimeSpan(0, 0, 15)),
Cache.NoSlidingExpiration, CacheItemPriority.Normal, null);
}
Mais je me demande, est-ce code thread-safe? La méthode de service web est appelée par plusieurs demandeurs. Et plus d'un demandeur peuvent tenter de récupérer les données et les ajouter à la Cache
dans le même temps, tandis que le cache est vide.
La requête prend 5 à 8 secondes. Serait l'introduction d'une instruction lock autour de ce code de prévenir d'éventuels conflits? (Je sais que plusieurs requêtes peuvent être exécutées simultanément, mais je veux être sûr qu'une seule requête à la fois.)
source d'informationauteur Burak SARICA
Vous devez vous connecter pour publier un commentaire.
L'objet dans le cache est thread-safe mais
HttpContext.Current
ne sera pas disponible à partir de threads d'arrière-plan. Cela peut ou peut ne pas s'appliquer à vous ici, il n'est pas évident à partir de votre extrait de code si oui ou non vous êtes réellement en utilisant des threads d'arrière-plan, mais dans le cas où vous êtes maintenant ou décider à un certain moment dans l'avenir, vous devez garder cela à l'esprit.Si il n'y a aucune chance que vous aurez besoin pour accéder à la cache à partir d'un thread d'arrière-plan, puis utilisez HttpRuntime.Cache à la place.
En outre, bien que les opérations sur la mémoire cache sont thread-safe, séquentielle de recherche/les opérations de banque sont évidemment pas atomique. Si oui ou non vous besoin à être atomique dépend de votre application particulière. Si elle pouvait être un problème sérieux pour la même requête à exécuter plusieurs fois, c'est à dire si il serait de produire plus de charge que votre base de données est capable de manipuler, ou si ce serait un problème pour une demande de données sur le rendement qui est immédiatement remplacé dans le cache, alors vous voudrez probablement pour placer un verrou autour de l'ensemble du bloc de code.
Cependant, dans la plupart des cas, vous voulez vraiment le profil de la première et de voir si oui ou non ce est en fait un problème. La plupart des applications web/services de ne pas se préoccuper de cet aspect de la mise en cache parce qu'ils sont apatrides et il n'a pas d'importance si le cache est écrasée.
Vous sont corrects. La récupération et l'ajout d'opérations ne sont pas traités comme une transaction atomique. Si vous avez besoin pour prévenir la requête à partir de l'exécution de plusieurs fois, vous aurez besoin d'utiliser un verrou.
(Normalement ce ne sera pas un problème, mais dans le cas d'un long temps d'exécution d'une requête, il peut être utile pour soulager la tension sur la base de données.)
Je crois que le
Add
doit être thread-safe, c'est à dire qu'il ne sera pas d'erreur siAdd
est appelée deux fois avec la même clé, mais, évidemment, la requête peut exécuter deux fois.Une autre question, cependant, est de données est thread-safe. Il n'y a aucune garantie que chaque
List<blabla>
est isolé - cela dépend de cache-fournisseur. Le cache en mémoire fournisseur de magasins directement les objets, il y a donc un risque de collision si l'un des threads modifier les données (ajouter/supprimer/swap éléments dans la liste, ou modifier les propriétés de l'un des éléments). Cependant, avec un la sérialisation fournisseur, vous devriez être bien. Bien sûr, cela exige alors queblabla
est sérialisable...