我无法理解MailboxProcessor
F# 中的“完成”时间。
我收集了一些行为(可能)违反直觉的例子。
该邮箱处理器不打印任何内容并停止程序:
let m = MailboxProcessor.Start (fun inbox -> async {
while true do
let! m = inbox.Receive()
printfn "%i" m
})
Run Code Online (Sandbox Code Playgroud)
该邮箱处理器计数直到2207
程序退出:
MailboxProcessor.Start (fun inbox -> async {
let mutable i = 0;
while true do
printfn "%i" i
i <- i + 1
})
|> ignore
Run Code Online (Sandbox Code Playgroud)
该邮箱处理器打印1
然后程序退出:
let m = MailboxProcessor.Start (fun inbox -> async {
while true do
let! m = inbox.Receive()
printfn "%i" m
do! Async.FromContinuations ignore // Should wait forever
})
m.Post(1)
m.Post(2)
m.Post(3)
Run Code Online (Sandbox Code Playgroud)
你能解释一下为什么MailboxProcessor
会有这样的行为吗?
启动时,MailboxProcessor
将运行指定为主体的异步计算。它将继续运行,直到主体完成(通过到达末尾或抛出异常)或直到程序本身终止(因为邮箱处理器在后台运行)。
对你的例子发表评论:
该邮箱处理器不打印任何内容并停止程序- 我假设您在控制台应用程序中运行它,该应用程序在创建邮箱处理器后终止。没有任何东西阻止程序,因此它结束(在后台杀死邮箱处理器)。
这个邮箱处理器计数到 2207 然后程序退出- 我怀疑这是出于同样的原因 - 你的程序创建邮箱处理器,它设法运行一段时间,但随后程序本身被终止,邮箱处理器被杀死。
该邮箱处理器打印 1,然后程序退出- 邮箱处理器的主体挂起,接下来的两条消息排队。队列永远不会被处理(因为主体已挂起),然后您的程序终止。
如果您在Console.ReadLine()
程序末尾添加类似的内容,您将获得更有用的见解,因为这将防止程序终止并杀死邮箱处理器。
例如,以下将处理所有 100000 个项目:
let mbox = MailboxProcessor.Start (fun inbox -> async {
while true do
let! msg = inbox.Receive()
printfn "%d" msg
})
for i in 0 .. 100000 do mbox.Post(i)
System.Console.ReadLine()
Run Code Online (Sandbox Code Playgroud)