MemoryCache Fil De Sécurité, Verrouillage Nécessaire?

Pour commencer, permettez-moi de simplement le jeter là-bas que je sais que le code ci-dessous n'est pas thread-safe (correction: peut-être). Ce que je suis mal, c'est de trouver une implémentation et une que je peux réellement obtenir à l'échec en cours de test. Je suis refactoring un grand WCF projet qui a besoin de certains (la plupart) statique des données mises en cache et son rempli à partir d'une base de données SQL. Il doit expirer et "actualiser" au moins une fois par jour, c'est pourquoi je suis à l'aide de MemoryCache.

Je sais que le code ci-dessous ne doivent pas être thread-safe, mais je ne peux pas l'obtenir à l'échec sous une lourde charge et pour compliquer les choses d'une recherche sur google montre les implémentations de deux façons (avec et sans verrous débats qu'ils soient ou non nécessaire.

Quelqu'un pourrait-il avec la connaissance de MemoryCache dans un environnement multithread laissez-moi définitivement savoir si oui ou non j'ai besoin de verrouiller le cas échéant, de sorte qu'un appel à supprimer (ce qui sera rarement appelé, mais son exigence) ne pas jeter lors de la récupération/le repeuplement.

public class MemoryCacheService : IMemoryCacheService
{
private const string PunctuationMapCacheKey = "punctuationMaps";
private static readonly ObjectCache Cache;
private readonly IAdoNet _adoNet;
static MemoryCacheService()
{
Cache = MemoryCache.Default;
}
public MemoryCacheService(IAdoNet adoNet)
{
_adoNet = adoNet;
}
public void ClearPunctuationMaps()
{
Cache.Remove(PunctuationMapCacheKey);
}
public IEnumerable GetPunctuationMaps()
{
if (Cache.Contains(PunctuationMapCacheKey))
{
return (IEnumerable) Cache.Get(PunctuationMapCacheKey);
}
var punctuationMaps = GetPunctuationMappings();
if (punctuationMaps == null)
{
throw new ApplicationException("Unable to retrieve punctuation mappings from the database.");
}
if (punctuationMaps.Cast<IPunctuationMapDto>().Any(p => p.UntaggedValue == null || p.TaggedValue == null))
{
throw new ApplicationException("Null values detected in Untagged or Tagged punctuation mappings.");
}
//Store data in the cache
var cacheItemPolicy = new CacheItemPolicy
{
AbsoluteExpiration = DateTime.Now.AddDays(1.0)
};
Cache.AddOrGetExisting(PunctuationMapCacheKey, punctuationMaps, cacheItemPolicy);
return punctuationMaps;
}
//Go oldschool ADO.NET to break the dependency on the entity framework and need to inject the database handler to populate cache
private IEnumerable GetPunctuationMappings()
{
var table = _adoNet.ExecuteSelectCommand("SELECT [id], [TaggedValue],[UntaggedValue] FROM [dbo].[PunctuationMapper]", CommandType.Text);
if (table != null && table.Rows.Count != 0)
{
return AutoMapper.Mapper.DynamicMap<IDataReader, IEnumerable<PunctuationMapDto>>(table.CreateDataReader());
}
return null;
}
}
  • ObjectCache est thread-safe, je ne pense pas que votre classe peut échouer. msdn.microsoft.com/en-us/library/... Vous avez peut-être aller à la base de données en même temps, mais qui ne fera que l'utilisation cpu plus que nécessaire.
  • Alors que ObjectCache est thread-safe, la mise en œuvre de celui-ci peut ne pas l'être. Ainsi, le MemoryCache question.
InformationsquelleAutor James Legan | 2013-11-22