【发布时间】:2014-01-13 22:43:24
【问题描述】:
我有以下类型来实现一个简单的惰性缓存:
module CachedFoo =
let mutable private lastAccess:Option<DateTime> = None
// returns a lazy value that initializes the cache when
// accessed for the first time (safely)
let private createCacheInitialization() =
lazy(
let someObject = SomeLongRunningOperation()
lastAccess <- Option.Some(DateTime.Now)
someObject
)
// current cache represented as lazy value
let mutable private currentCache = createCacheInitialization()
// Reset - cache will be re-initialized next time it is accessed
// (this doesn't actually initialize a cache - just creates a lazy value)
let MaybeReset() =
if (lastAccess.IsSome && DateTime.Now > (lastAccess.Value + TimeSpan.FromSeconds (10.0))) then
currentCache <- createCacheInitialization()
let GetCache() =
MaybeReset()
currentCache.Value
第一个问题:上面的线程安全吗?默认情况下,lazy() 似乎是线程安全的,但我想我需要在 lastAccess 字段的分配周围加锁?
第二个也是最重要的:这是惰性的,因为它的值在有人需要它之前不会被检索,但是,我认为我什至可以通过返回最后一个缓存的对象来做得更惰性,即使在 Reset( ) 被调用,但是在后台启动一个异步线程来调用这个方法。
在 C# 中是这样的:
public SomeObject GetCache() {
try {
return currentCache.Value;
} finally {
ThreadPool.QueueUserWorkItem(new WaitCallback(MaybeReset));
}
}
我将如何在 F# 中做到这一点? (如果解决方案使用花哨的异步东西而不是使用 ThreadPool API,则加分)。
【问题讨论】:
-
超时的原因是什么 - 它似乎并没有节省内存,因为它只在有人真正说他们想要这个值时触发?缓存的结果会以某种方式过时吗?
-
是的,他们可以,但如果我能够找到一种方法在 F# 中对此进行编码,我将简单地减少超时以解决“陈旧”概率的增加
标签: multithreading asynchronous f# lazy-evaluation c#-to-f#