我暂时写了这个方法:
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
方法中是否遗漏了任何可能导致无意中被强烈引用的内容? - 我是不是为了自己的利益太聪明了?- 即使不需要,我是否应该只招致命中并将数据缓存在普通的局部变量中?
我怀疑我可能太聪明了,但即使我是,这在其他人看来是否像一个可以在其他情况下有用的解决方案?
更新:修改功能,因为显然你不能信任 .IsAlive
更新:我意识到返回的Func
将在方法结束时超出范围,所以我根本不需要弱引用,普通的引用就可以了。我认为我正遭受“只见树木不见森林”的情况。