Самовосстанавливающийся MemoryCache
Я реализовал кэш, который обновляет содержащиеся значения, когда они истекают.
Мой код такой:
class MyCache
{
private static readonly MemoryCache Cache = MemoryCache.Default;
private CacheItemPolicy _errorpolicy;
private CacheItemPolicy _warnPolicy;
private CacheEntryRemovedCallback _warnCacheEntryRemovedCallback;
private CacheEntryRemovedCallback _errorCacheEntryRemovedCallback;
public void AddErrors(string key, object errors)
{
_errorCacheEntryRemovedCallback = ErrorItemRemovedCallback;
_errorpolicy = new CacheItemPolicy
{
AbsoluteExpiration = DateTimeOffset.Now.AddSeconds(7.00),
RemovedCallback = _errorCacheEntryRemovedCallback
};
Cache.Set(key, errors, _errorpolicy);
}
public void AddWarnings(string key, object warnings)
{
_warnCacheEntryRemovedCallback = WarningCacheItemRemovedCallback;
_warnPolicy = new CacheItemPolicy
{
AbsoluteExpiration = DateTimeOffset.Now.AddSeconds(4.00),
RemovedCallback = _warnCacheEntryRemovedCallback
};
Cache.Set(key, warnings, _warnPolicy);
}
private void ErrorItemRemovedCallback(CacheEntryRemovedArguments arguments)
{
Console.WriteLine("{0} Item removed: {1}", DateTime.UtcNow, arguments.CacheItem.Key);
Cache.Set(arguments.CacheItem.Key, new List<string> { "error1", "error2", "error3" }, _errorpolicy);
}
private void WarningCacheItemRemovedCallback(CacheEntryRemovedArguments arguments)
{
Console.WriteLine("{0} Item removed: {1}", DateTime.UtcNow, arguments.CacheItem.Key);
Cache.Set(arguments.CacheItem.Key, new List<string> { "warn1", "warn2", "warn3" }, _warnPolicy);
}
}
Но что-то не так.
Выше написано это в приглашении:
04-05-2014 21:20:00 Item removed: warn
04-05-2014 21:20:00 Item removed: error
04-05-2014 21:20:20 Item removed: error
04-05-2014 21:20:20 Item removed: warn
04-05-2014 21:20:40 Item removed: warn
04-05-2014 21:20:40 Item removed: error
04-05-2014 21:20:40 Item removed: error
04-05-2014 21:20:40 Item removed: warn
... и я бы ожидал что-то вроде
04-05-2014 21:20:04 Item removed: warn
04-05-2014 21:20:07 Item removed: error
04-05-2014 21:20:08 Item removed: warn
04-05-2014 21:20:12 Item removed: warn
04-05-2014 21:20:14 Item removed: error
...
Что мне не хватает?
Обновление 2014-05-14:
Я изменил переменные уровня поля на локальные переменные - но такое же поведение существует. Также обратите внимание, что последовательность удаления из кэша изменяется - сначала это "ошибки-потом-предупреждения" - но в следующий раз это "предупреждает-потом-ошибки".
Также обратите внимание, что первое удаление из кэша происходит через 21 секунду - после этого оно происходит постоянно каждые 20 секунд.
14-05-2014 13:00:59 Adding errors to cache
14-05-2014 13:00:59 Adding warnings to cache
Press 'q' to quit
14-05-2014 13:01:20 Item removed: warn
14-05-2014 13:01:20 Item removed: error
14-05-2014 13:01:40 Item removed: error
14-05-2014 13:01:40 Item removed: warn
14-05-2014 13:02:00 Item removed: warn
14-05-2014 13:02:00 Item removed: error
14-05-2014 13:02:20 Item removed: error
14-05-2014 13:02:20 Item removed: warn
14-05-2014 13:02:40 Item removed: warn
14-05-2014 13:02:40 Item removed: error
Весь мой (новый код) здесь:
namespace DemoCache
{
internal class Program
{
private static readonly List<string> ErrorList = new List<string> {"error1", "error2", "error3"};
private static readonly List<string> WarningList = new List<string> {"warn1", "warn2", "warn3"};
static void Main()
{
var myCache = new MyCache();
Console.WriteLine("{0} Adding errors to cache ", DateTime.UtcNow);
myCache.AddErrors("error", ErrorList);
Console.WriteLine("{0} Adding warnings to cache", DateTime.UtcNow);
myCache.AddWarnings("warn", WarningList);
Console.WriteLine("Press 'q' to quit");
var keepRunning = true;
do
{
var key = Console.ReadKey(true);
switch (Char.ToLower(key.KeyChar))
{
case 'q':
keepRunning = false;
break;
}
} while (keepRunning);
}
}
class MyCache
{
private static readonly MemoryCache Cache = new MemoryCache("name");
//private CacheItemPolicy _errorpolicy;
//private CacheItemPolicy _warnPolicy;
//private CacheEntryRemovedCallback _warnCacheEntryRemovedCallback;
//private CacheEntryRemovedCallback _errorCacheEntryRemovedCallback;
public void AddErrors(string key, object errors)
{
CacheEntryRemovedCallback errorCacheEntryRemovedCallback = ErrorItemRemovedCallback;
var errorpolicy = new CacheItemPolicy
{
AbsoluteExpiration = DateTime.Now.AddSeconds(7.00),
RemovedCallback = errorCacheEntryRemovedCallback
};
Cache.Set(key, errors, errorpolicy);
}
public void AddWarnings(string key, object warnings)
{
CacheEntryRemovedCallback warnCacheEntryRemovedCallback = WarningCacheItemRemovedCallback;
var warnPolicy = new CacheItemPolicy
{
AbsoluteExpiration = DateTime.Now.AddSeconds(11.00),
RemovedCallback = warnCacheEntryRemovedCallback
};
Cache.Set(key, warnings, warnPolicy);
}
private void ErrorItemRemovedCallback(CacheEntryRemovedArguments arguments)
{
Console.WriteLine("{0} Item removed: {1}", DateTime.UtcNow, arguments.CacheItem.Key);
AddErrors(arguments.CacheItem.Key, new List<string> { "error1", "error2", "error3" });
//Cache.Set(arguments.CacheItem.Key, , _errorpolicy);
}
private void WarningCacheItemRemovedCallback(CacheEntryRemovedArguments arguments)
{
Console.WriteLine("{0} Item removed: {1}", DateTime.UtcNow, arguments.CacheItem.Key);
AddWarnings(arguments.CacheItem.Key, new List<string> { "warn1", "warn2", "warn3" });
//Cache.Set(arguments.CacheItem.Key, new List<string> { "warn1", "warn2", "warn3" }, _warnPolicy);
}
}
}