I managed to squeeze out a bit of extra perf by removing boxing and unboxing and not losing any implementation of the original in the CacheEntry object in MemoryCacheClient.
private ConcurrentDictionary<string, ICacheEntry> memory;
private interface ICacheEntry
{
DateTime? ExpiresAt { get; set; }
long LastModifiedTicks { get; set; }
bool HasExpired { get; }
}
private class CacheEntry<T> : ICacheEntry
{
private T cacheValue;
/// <summary>
/// Create new instance of CacheEntry.
/// </summary>
public CacheEntry(T value, DateTime? expiresAt)
{
Value = value;
ExpiresAt = expiresAt;
LastModifiedTicks = DateTime.UtcNow.Ticks;
}
internal T Value
{
get { return cacheValue; }
set
{
cacheValue = value;
LastModifiedTicks = DateTime.UtcNow.Ticks;
}
}
/// <summary>UTC time at which CacheEntry expires.</summary>
public DateTime? ExpiresAt { get; set; }
public bool HasExpired => ExpiresAt != null && ExpiresAt < DateTime.UtcNow;
public long LastModifiedTicks { get; set; }
}
Could be worth checking out?