I have a ConcurrentDictionary that I use as a hash table that will refresh at a regular time interval. the TValue of my ConcurrentDictionary is a custom class that I created :
public class RefreshableDictionaryValue<TValue>
{
private DateTime lastRefreshed;
private DateTime lastAccessed;
private TValue value;
public override bool Equals(object obj)
{
if (obj == null)
{
return false;
}
TValue t = (TValue)obj;
if((System.Object)t == null)
{
return false;
}
return this.Value.Equals(((RefreshableDictionaryValue<TValue>)obj).Value);
}
public override int GetHashCode()
{
return Value.GetHashCode();
}
...
}
I assume ConcurrentDictionary uses equals to compare values of two objects and I have overriden Equals for my class so that it returns true if the TValues are equal. The dates can be different. I also tried ineriting from IEqualityComparer<RefreshableDictionaryValue<TValue>>
but that had no effect.
If I don't override Equals then TryUpdate returns false(obviously, cause the objects I'm comparing will have the same TValue but different dates) and if I do override equals I get this error
> Error while refreshing dictionary System.InvalidCastException: Unable
> to cast object of type
> ItemRefreshableDictionary.RefreshableDictionaryValue`1[StatsHelper.Stats]'
> to type 'StatsHelper.Stats'. at
> ItemRefreshableDictionary.RefreshableDictionaryValue`1.Equals(Object
> obj) in
> \Projects\StatsHelper\ItemLevelRefreshableDictionary\ItemLevelRefreshableDictionary.cs:line
> 24 at System.Collections.Generic.ObjectEqualityComparer`1.Equals(T
> x, T y) at
> System.Collections.Concurrent.ConcurrentDictionary`2.TryUpdate(TKey
> key, T Value newValue, TValue comparisonValue)
Edit: Here's how I do the update:
foreach(KeyValuePair<TKey, RefreshableDictionaryValue<TValue>> entry in cacheDictionary)
{
DateTime lastRefresh = entry.Value.LastRefreshed;
DateTime lastAccess = entry.Value.LastAccessed;
secondsSinceLastRefresh = Convert.ToInt32((DateTime.Now - lastRefresh).TotalSeconds);
secondsSinceLastAccess = Convert.ToInt32((DateTime.Now - lastAccess).TotalSeconds);
if (secondsSinceLastAccess < cacheExpirationTime)
{
if (secondsSinceLastRefresh > refreshInterval)
{
TValue updatedValue = valueGetter(entry.Key);
bool s = cacheDictionary.TryUpdate(entry.Key, new RefreshableDictionaryValue<TValue>(DateTime.Now, lastAccess, updatedValue), entry.Value);
}
}
}