나는 시험 적으로이 방법을 서면으로 작성했습니다 :이 캐싱 기능이 작동하는 방식으로 작동합니까?
public static Func<T> WeakCacheFor<T>(Func<T> provider) where T: class
{
var cache = new WeakReference(null);
return() => {
var x = (T)cache.Target;
if(x == null)
{
x = provider();
cache.Target = x;
}
return x;
};
}
그래서 약간의 배경 : 나는 조금 다음과 같이 몇 가지 장황한 기존의 방법이
:
var id = GetDatabaseId();
if(a){
var data = GetLoader().Init(id).GetData(); // expensive!
// do stuff with data
}
if(b){
// don't load data
}
... lots more variations, some contain GetLoader().Init(id).GetData(); some don't....
내 가능한 해결책은 다음과 같습니다.
var id = GetDatabaseId();
var loadData = WeakCacheFor(() => GetLoader().Init(id).GetData());
if(a){
var data = loadData();
// do stuff with data
}
if(b){
// don't load data
}
... lots more variations, some contain loadData(); some don't....
내 생각 이 약의 :이 메서드 호출의 범위를 넘어 캐시 할 필요가 없습니다, 그래서 GC가 그것을 수집하는 경우 방법은
- 데이터를로드 할 필요가 없습니다. 히트는 발생하지 않습니다.
- 데이터가 필요한 경우 다시 필요한 경우 약한 참조에 캐시됩니다.
- GC가 중간 지점을 수집하는 경우 다시로드되기 때문에 중요하지 않습니다.
내 질문 :
- 이 실제로 작동합니까? -
WeakCacheFor
방법에서 놓친 부분이있어 강력하게 참조 할 수 없습니까? - 나는 내 자신을 위해서 너무 똑똑한가요? - 필요하지 않은 경우에도 데이터를 히트하고 정상 로컬 변수에 캐시해야합니까?
나는 너무 영리하다고 생각하지만, 비록 내가 그렇다고해도, 다른 상황에서 유용하게 적용될 수있는 해결책과 같은 다른 사람에게 보이나요 ??
업데이트 : 수정 기능 때문에 apparently you can't trust .IsAlive
업데이트 : 반환 된 Func
이 방법의 끝에서 범위를 벗어난 갈 것이다, 그래서 모두에서 weakref를 필요로하지 않고 정상적인 심판이 작동 실현 잘 됐네. 나는 "나무를위한 숲을 볼 수 없다"고 생각했다.
가 - 객체의 유형은 매우 분명하다 때 유용합니다 (예 : VAR NewList = List)하지만 많은 경우에는 그렇지 않습니다. –
좋은 지적. 반환 된 람다 함수는 호출 메서드의 끝 부분에서 범위를 벗어나므로 weakref가 나에게 아무 것도 사지 않는다. var의 '남용'에 대해서는 동의하지 않습니다. var를 사용하지 않는 이유는 무엇입니까? –
var 키워드를 사용하면 유형이 무엇인지, 어디서 코드를 읽기 쉽도록하는지 분명하게 알 수 있습니다. 오른쪽면이 유형을 표시하지 않으면 유형 이름을 사용해야합니다 (예 : 예에서 ID 및 데이터 변수). – Guffa