2009-04-16 3 views
1

개발중인 웹 사이트에 대한 고유 한 캐시 관리자를 만들었으며 특정 상황에서 캐시를 지우는 가장 좋은 방법을 찾고있었습니다. HttpRuntime Close는 광고 된대로 캐시에서 항목을 제거하지 않습니다.

나는 캐시를 삭제하는 적절한 방법을 말하는 많은 기사가 나는 캡슐화 된 기능 HttpRuntime.Close()를 호출 내 단위 테스트 설정에서,

그러나 HttpRuntime.Close()를 호출하는 것입니다 발견 캐시가 아닙니다 지우고있다.

가 나는

foreach (DictionaryEntry cacheItem in HttpRuntime.Cache) 
{ 
    HttpRuntime.Cache.Remove(cacheItem.Key.ToString()); 
} 

foreach는 루프 내 캡슐화 된 기능에 좋은 작품에 비슷한 일을 수행 할 것으로 예상하지만, 닫기() 결코 잘 작동하지 않습니다.

나는 HttpRuntime.Close()의 목적을 오해하고 있습니까? 아니면 여기에 더 불길한 일이 있습니까?

답변

9

사용하지 마십시오. 문서가 말하는 것 이상입니다. 그리고 문서도

이 반사 닫기()의 소스입니다 ... 정상적인 요청을 처리하는 동안하지 그것을 사용하는 말 : 또한

[SecurityPermission(SecurityAction.Demand, Unrestricted=true)] 
public static void Close() { 
    if (_theRuntime.InitiateShutdownOnce()) { 
     SetShutdownReason(ApplicationShutdownReason.HttpRuntimeClose, "HttpRuntime.Close is called"); 
     if (HostingEnvironment.IsHosted) { 
      HostingEnvironment.InitiateShutdown(); 
     } else { 
      _theRuntime.Dispose(); 
     } 
    } 
} 

, 당신은 컬렉션을 반복하고 그것에서 항목을 제거 할 수 없습니다 동시에, 이것은 열거를 무효로 렌더링합니다.

그래서,이 끝난 루프 무엇을 변경하지 않는 대신이 시도 :

List<string> toRemove = new List<string>(); 
foreach (DictionaryEntry cacheItem in HttpRuntime.Cache) { 
    toRemove.Add(cacheItem.Key.ToString()); 
} 
foreach (string key in toRemove) { 
    HttpRuntime.Cache.Remove(key); 
} 

말했다되고 그건 정말, 당신은 당신을 위해 자동으로 지워 잘못된 캐시 항목을 가지고 캐시 종속성을 사용하려고합니다 , 그리고이 모든 것이 불필요해진다.

+0

을 실제로 이미했습니다 다음

public sealed class YourCache<T> { private Dictionary<string, T> _dictionary = new Dictionary<string, T>(); private YourCache() { } public static YourCache<T> Current { get { string key = "YourCache|" + typeof(T).FullName; YourCache<T> current = HttpContext.Current.Cache[key] as YourCache<T>; if (current == null) { current = new YourCache<T>(); HttpContext.Current.Cache[key] = current; } return current; } } public T Get(string key, T defaultValue) { if (string.IsNullOrWhiteSpace(key)) throw new ArgumentNullException("key should not be NULL"); T value; if (_dictionary.TryGetValue(key, out value)) return value; return defaultValue; } public void Set(string key, T value) { if (key == null) throw new ArgumentNullException("key"); _dictionary[key] = value; } public void Clear() { _dictionary.Clear(); } } 

당신이 캐시에서 항목을 호출 할 수 있습니다 또는 분명 그들이 사용 내 질문에 넣어 코드를 테스트하고 잘 작동합니다. 열거 형 문제는 이해하지만 캐시가 목록을 보면서 항목을 제거하는 데 문제가없는 것처럼 보입니다. – Joseph

+0

그건 내 질문이 아니야. 제가 말하고자하는 것은, 캐시에 4 개의 아이템이 있고 그것을 설명한대로 반복하면 캐시는 0 개의 아이템으로 끝납니다. 그러나 Close()를 사용하면 4 개의 항목이 여전히 존재합니다. – Joseph

+0

문서가 완전한 진실이 아닌 것을 진술하기 때문입니다.Close()는 캐시를 지우는 데 사용되지 않습니다. – Lucero

4

내가 열거와 함께 문제를 이해하지만, 어떤 이유로 캐시 목록을 걷는 동안 항목을 제거하는 문제가있는 것 같지 않습니다.

당신은 세부 구현에 드릴 다운하면, 당신은 열거를 찾을 수는 CacheSingle.CreateEnumerator에 의해 만들어진, 새로운 해시 테이블 인스턴스를 열거 생성됩니다.

그래서 foreach 루프에서 제거 작업을 수행 할 수 있습니다.

0

당신은 단순히 자신의 캐시 클래스를 구현할 수, 하나 아래의 사항을 확인하십시오

// put something in this intermediate cache 
YourCache<ClassObject>.Current.Set("myKey", myObj); 

// clear this cache 
YourCache<ClassObject>.Current.Clear(); 
관련 문제