I have written my own custom change monitor class for the .NET MemoryCache. It seems to initialize fine, but when I attempt to add it to the Cache, it throws an InvalidOperation
exception - The method has already been invoked, and can only be invoked once.
My change monitor class:
internal class MyChangeMonitor : ChangeMonitor
{
private Timer _timer;
private readonly string _uniqueId;
private readonly TypeAsOf _typeAsOf;
private readonly string _tableName;
public GprsChangeMonitor(TypeAsOf typeAsOf, string tableName)
{
bool initComplete = false;
try
{
_typeAsOf = typeAsOf;
_tableName = tableName;
_uniqueId = Guid.NewGuid().ToString();
TimeSpan ts = new TimeSpan(0, 0, 5, 0, 0);
_timer = new Timer {Interval = ts.TotalMilliseconds};
_timer.Elapsed += CheckForChanges;
_timer.Enabled = true;
_timer.Start();
initComplete = true;
}
finally
{
base.InitializationComplete();
if(!initComplete)
Dispose(true);
}
}
void CheckForChanges(object sender, System.Timers.ElapsedEventArgs e)
{
//check for changes, if different
base.OnChanged(_typeAsOf);
}
}
The code I use to create the cache policy and add the key/value pair to the cache:
CacheItemPolicy policy = new CacheItemPolicy
{
UpdateCallback = OnCacheEntryUpdateCallback
};
policy.AbsoluteExpiration = SystemTime.Today.AddHours(24);
//monitor the for changes
string tableName = QuickRefreshItems[type];
MyChangeMonitor cm = new MyChangeMonitor(typeAsOf, tableName);
policy.ChangeMonitors.Add(cm);
cm.NotifyOnChanged(OnRefreshQuickLoadCacheItems);
MyCache.Set(cacheKey, value, policy);
The Set
call throws the invalid operation exception which is weird because, according to the MSDN documentation, it only throws the ArgumentNull
, Argument
, ArgumentOutOfRange
, and NotSupported
exceptions.
I am sure that I must be making a simple mistake. But it's hard to find good documentation or examples on writing your own custom change monitor. Any help would be appreciated.
I know the comments have the answer, but I wanted it to be more obvious...
When a ChangeMonitor
is used, it will fire immediately if the cache entry does not exist.
MSDN documentation states it this way:
A monitored entry is considered to have changed for any of the following reasons:
A) The key does not exist at the time of the call to the CreateCacheEntryChangeMonitor method. In that case, the resulting CacheEntryChangeMonitor instance is immediately set to a changed state. This means that when code subsequently binds a change-notification callback, the callback is triggered immediately.
B) The associated cache entry was removed from the cache. This can occur if the entry is explicitly removed, if it expires, or if it is evicted to recover memory
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With