在 John Palmer 在评论中指出明显错误后更新。
以下代码导致OutOfMemoryException
:
let agent = MailboxProcessor<string>.Start(fun agent ->
let maxLength = 1000
let rec loop (state: string list) i = async {
let! msg = agent.Receive()
try
printfn "received message: %s, iteration: %i, length: %i" msg i state.Length
let newState = state |> Seq.truncate maxLength |> Seq.toList
return! loop (msg::newState) (i+1)
with
| ex ->
printfn "%A" ex
return! loop state (i+1)
}
loop [] 0
)
let greeting = "hello"
while true do
agent.Post greeting
System.Threading.Thread.Sleep(1) // avoid piling up greetings before they are output
如果我不使用 try/catch 块,错误就消失了。
增加睡眠时间只会推迟错误。
更新 2:我想这里的问题是函数停止尾递归,因为递归调用不再是最后一个执行的调用。对于具有更多 F# 经验的人来说,将其脱糖会很好,因为我确信这是 F# 代理中常见的内存泄漏情况,因为代码非常简单和通用。