gpt4 book ai didi

c# - MemoryCache 线程安全,是否需要加锁?

转载 作者:IT王子 更新时间:2023-10-29 03:42:49 34 4
gpt4 key购买 nike

对于初学者,让我把它扔在那里,我知道下面的代码不是线程安全的(更正:可能是)。我正在苦苦挣扎的是找到一种实现,并且我实际上可以在测试中失败。我现在正在重构一个大型 WCF 项目,该项目需要缓存一些(大部分)静态数据并从 SQL 数据库中填充这些数据。它需要每天至少过期和“刷新”一次,这就是我使用 MemoryCache 的原因。

我知道下面的代码不应该是线程安全的,但我不能让它在重负载下失败并且使事情复杂化谷歌搜索显示两种方式的实现(有锁和没有锁以及是否需要锁的争论。

在多线程环境中了解 MemoryCache 的人能否让我明确地知道我是否需要在适当的地方锁定,以便在检索期间不会抛出删除调用(很少被调用,但它是一个要求)/重新填充。

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;
}
}

最佳答案

MS 提供的默认 MemoryCache 是完全线程安全的。派生自 MemoryCache 的任何自定义实现都可能不是线程安全的。如果您使用开箱即用的普通 MemoryCache,它是线程安全的。浏览我的开源分布式缓存解决方案的源代码,看看我是如何使用它的(MemCache.cs):

https://github.com/haneytron/dache/blob/master/Dache.CacheHost/Storage/MemCache.cs

关于c# - MemoryCache 线程安全,是否需要加锁?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20149796/

34 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com