e79aa3c0ed
Former-commit-id: a2155e9bd80020e49e72e86c44da02a8ac0e57a4
128 lines
5.2 KiB
C#
128 lines
5.2 KiB
C#
// <copyright file="MemoryCacheEntryChangeMonitor.cs" company="Microsoft">
|
|
// Copyright (c) 2009 Microsoft Corporation. All rights reserved.
|
|
// </copyright>
|
|
using System;
|
|
using System.Runtime.Caching.Resources;
|
|
using System.Collections.Generic;
|
|
using System.Collections.ObjectModel;
|
|
using System.Diagnostics.CodeAnalysis;
|
|
using System.Globalization;
|
|
using System.Text;
|
|
|
|
namespace System.Runtime.Caching {
|
|
internal sealed class MemoryCacheEntryChangeMonitor : CacheEntryChangeMonitor {
|
|
// Dev10 909507: use UTC minimum DateTime for error free conversions to DateTimeOffset
|
|
private static readonly DateTime DATETIME_MINVALUE_UTC = new DateTime(0, DateTimeKind.Utc);
|
|
private const int MAX_CHAR_COUNT_OF_LONG_CONVERTED_TO_HEXADECIMAL_STRING = 16;
|
|
private ReadOnlyCollection<String> _keys;
|
|
private String _regionName;
|
|
private String _uniqueId;
|
|
private DateTimeOffset _lastModified;
|
|
private List<MemoryCacheEntry> _dependencies;
|
|
|
|
private MemoryCacheEntryChangeMonitor() {} // hide default .ctor
|
|
|
|
private void InitDisposableMembers(MemoryCache cache) {
|
|
bool dispose = true;
|
|
try {
|
|
bool hasChanged = false;
|
|
string uniqueId = null;
|
|
_dependencies = new List<MemoryCacheEntry>(_keys.Count);
|
|
if (_keys.Count == 1) {
|
|
string k = _keys[0];
|
|
MemoryCacheEntry entry = cache.GetEntry(k);
|
|
DateTime utcCreated = DATETIME_MINVALUE_UTC;
|
|
StartMonitoring(cache, entry, ref hasChanged, ref utcCreated);
|
|
uniqueId = k + utcCreated.Ticks.ToString("X", CultureInfo.InvariantCulture);
|
|
_lastModified = utcCreated;
|
|
}
|
|
else {
|
|
int capacity = 0;
|
|
foreach (string key in _keys) {
|
|
capacity += key.Length + MAX_CHAR_COUNT_OF_LONG_CONVERTED_TO_HEXADECIMAL_STRING;
|
|
}
|
|
StringBuilder sb = new StringBuilder(capacity);
|
|
foreach (string key in _keys) {
|
|
MemoryCacheEntry entry = cache.GetEntry(key);
|
|
DateTime utcCreated = DATETIME_MINVALUE_UTC;
|
|
StartMonitoring(cache, entry, ref hasChanged, ref utcCreated);
|
|
sb.Append(key);
|
|
sb.Append(utcCreated.Ticks.ToString("X", CultureInfo.InvariantCulture));
|
|
if (utcCreated > _lastModified) {
|
|
_lastModified = utcCreated;
|
|
}
|
|
}
|
|
uniqueId = sb.ToString();
|
|
}
|
|
_uniqueId = uniqueId;
|
|
if (hasChanged) {
|
|
OnChanged(null);
|
|
}
|
|
dispose = false;
|
|
}
|
|
finally {
|
|
InitializationComplete();
|
|
if (dispose) {
|
|
Dispose();
|
|
}
|
|
}
|
|
}
|
|
|
|
private void StartMonitoring(MemoryCache cache, MemoryCacheEntry entry, ref bool hasChanged, ref DateTime utcCreated) {
|
|
if (entry != null) {
|
|
// pass reference to self so the dependency can notify us when it changes
|
|
entry.AddDependent(cache, this);
|
|
// add dependency to collection so we can dispose it later
|
|
_dependencies.Add(entry);
|
|
// has the entry already changed?
|
|
if (entry.State != EntryState.AddedToCache) {
|
|
hasChanged = true;
|
|
}
|
|
utcCreated = entry.UtcCreated;
|
|
}
|
|
else {
|
|
// the entry does not exist--set hasChanged to true so the user is notified
|
|
hasChanged = true;
|
|
}
|
|
}
|
|
|
|
//
|
|
// protected members
|
|
//
|
|
|
|
protected override void Dispose(bool disposing) {
|
|
if (disposing) {
|
|
if (_dependencies != null) {
|
|
foreach (MemoryCacheEntry entry in _dependencies) {
|
|
if (entry != null) {
|
|
entry.RemoveDependent(this);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
//
|
|
// public and internal members
|
|
//
|
|
|
|
public override ReadOnlyCollection<string> CacheKeys { get { return new ReadOnlyCollection<string>(_keys); } }
|
|
public override string RegionName { get { return _regionName; } }
|
|
public override string UniqueId { get { return _uniqueId; } }
|
|
public override DateTimeOffset LastModified { get { return _lastModified; } }
|
|
internal List<MemoryCacheEntry> Dependencies { get { return _dependencies; } }
|
|
|
|
internal MemoryCacheEntryChangeMonitor(ReadOnlyCollection<String> keys, String regionName, MemoryCache cache) {
|
|
Dbg.Assert(keys != null && keys.Count > 0, "keys != null && keys.Count > 0");
|
|
_keys = keys;
|
|
_regionName = regionName;
|
|
InitDisposableMembers(cache);
|
|
}
|
|
|
|
// invoked by a cache entry dependency when it is released from the cache
|
|
internal void OnCacheEntryReleased() {
|
|
OnChanged(null);
|
|
}
|
|
}
|
|
}
|