2011-12-27 2 views
2

Как я могу кэшировать объекты, реализующие интерфейс IDisposable, используя CacheManager из Microsoft Enterprise Library?EntLib CacheManager и IDisposable objects

Когда объект истекает, Dispose() никогда не вызывается для этого объекта, и я не могу переопределить Remove (...).

+0

Можете ли вы назвать Dispose в деструктор объектов в кэше? Или у вас нет кода для этих классов? – rene

+0

У меня есть код для этих классов, и он даст ему шанс, хотя он как-то кажется взломанным. –

+0

полностью согласен, я надеюсь, что кто-то другой найдет лучшее решение – rene

ответ

2

Мне не совсем ясно, что ответственность за кеш должна быть вызвана Dispose; просто потому, что элемент удален из кеша, не означает, что он не ссылается нигде.

Кроме того, если объект реализует шаблон IDisposable, то Finalizer должен вызвать Dispose (если Dispose еще не был вызван).

Однако корпоративная библиотека предоставляет вам доступ, чтобы вы могли выполнять любые действия, которые считаете необходимыми. Интерфейс - это интерфейс ICacheItemRefreshAction. Когда элемент удаляется из кеша, метод ICacheItemRefreshAction.Refresh будет вызываться в отдельном потоке.

Когда элемент добавлен в кэш, можно указать ICacheItemRefreshAction.

Пример его использования:

[Serializable] 
public class DisposeRefreshAction : ICacheItemRefreshAction 
{ 
    public void Refresh(string key, object expiredValue, CacheItemRemovedReason removalReason) 
    { 
     // Item has been removed from cache. Perform desired actions here, based on 
     // the removal reason (for example, refresh the cache with the item). 
     if (expiredValue != null && expiredValue is IDisposable) 
     { 
      ((IDisposable)expiredValue).Dispose(); 
     } 

    } 
} 

public class MyClass : IDisposable 
{ 
    public void Dispose() 
    { 
     Console.WriteLine("Dispose!"); 
    } 
} 

var cache = EnterpriseLibraryContainer.Current.GetInstance<CacheManager>("Cache Manager"); 

cache.Add("myKey", new MyClass(), CacheItemPriority.Normal, 
    new DisposeRefreshAction(), new SlidingTime(TimeSpan.FromSeconds(2)));