Đối với người mới bắt đầu, hãy để tôi chỉ cần ném nó ra khỏi đó rằng tôi biết mã bên dưới không an toàn cho chuỗi (sửa: có thể là). Điều tôi đang đấu tranh là tìm ra một triển khai phù hợp và một cách mà tôi thực sự có thể gặp thất bại trong quá trình thử nghiệm. Tôi đang cấu trúc lại một dự án WCF lớn ngay bây giờ cần một số (chủ yếu) dữ liệu tĩnh được lưu trong bộ nhớ cache và được điền từ cơ sở dữ liệu SQL. Nó cần phải hết hạn và "làm mới" ít nhất một lần một ngày, đó là lý do tại sao tôi đang sử dụng MemoryCache.
Tôi biết rằng mã dưới đây không được an toàn cho chuỗi nhưng tôi không thể khiến nó không thành công khi tải nặng và làm phức tạp vấn đề, tìm kiếm trên google hiển thị các triển khai theo cả hai cách (có và không có khóa kết hợp với các cuộc tranh luận xem chúng có cần thiết hay không).
Ai đó có kiến thức về MemoryCache trong môi trường đa luồng có thể cho tôi biết chắc chắn liệu tôi có cần khóa ở nơi thích hợp hay không để lệnh gọi xóa (sẽ hiếm khi được gọi nhưng là yêu cầu của nó) sẽ không xảy ra trong quá trình truy xuất / lặp lại.
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;
}
}