Yeni başlayanlar için, aşağıdaki kodun iş parçacığı için güvenli olmadığını bildiğimi oraya atmama izin verin (düzeltme: olabilir). Mücadele ettiğim şey, gerçekten test altında başarısız olabileceğim bir uygulama bulmak. Şu anda bazı (çoğunlukla) statik verilerin önbelleğe alınması ve bir SQL veritabanından doldurulması gereken büyük bir WCF projesini yeniden oluşturuyorum. Günde en az bir kez süresinin dolması ve "yenilenmesi" gerekiyor, bu yüzden MemoryCache kullanıyorum.
Aşağıdaki kodun iş parçacığı açısından güvenli olmaması gerektiğini biliyorum, ancak ağır yük altında başarısız olmasını ve sorunları karmaşıklaştırmasını sağlayamıyorum, bir google arama uygulamaları her iki şekilde de gösterir (kilitli ve kilitsiz, gerekli olup olmadıkları tartışmalarla birlikte.
Çok iş parçacıklı bir ortamda MemoryCache bilgisine sahip biri, geri alma / yeniden doldurma sırasında kaldırılacak bir çağrının (nadiren çağrılacak, ancak bir gerekliliktir) atılmaması için uygun olduğunda kilitlemem gerekip gerekmediğini kesin olarak bana söyleyebilir mi?
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;
}
}