邮箱处理器何时停止 运行?

When does a mailbox processor stop running?

我无法理解 MailboxProcessor 在 F# 中“完成”的时间。

我收集了一些行为(可能)违反直觉的例子。

此邮箱处理器不打印任何内容并暂停程序:

let m = MailboxProcessor.Start (fun inbox -> async {
  while true do
    let! m = inbox.Receive()
    printfn "%i" m
})

此邮箱处理器计数到 2207 然后程序退出:

MailboxProcessor.Start (fun inbox -> async {
  let mutable i = 0;
  while true do
    printfn "%i" i
    i <- i + 1
})
|> ignore

此邮箱处理器打印 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)

你能解释一下为什么 MailboxProcessor 会这样吗?

启动时,MailboxProcessor将运行异步计算指定为正文。它将继续 运行ning 直到正文完成(通过到达结尾或通过抛出异常)或直到程序本身终止(作为后台的邮箱处理器 运行s)。

评论你的例子:

  • 此邮箱处理器不打印任何内容并暂停程序 - 我假设您 运行 在控制台应用程序中执行此操作,该应用程序在邮箱处理器运行后终止创建。没有任何东西阻止程序,所以它结束了(在后台杀死邮箱处理器)。

  • 这个邮箱处理器计数到 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()