1

我在消息循环中有一个超时异常(我真的打算设置一个超时),我试图按如下方式捕获它

let printerAgent = MailboxProcessor.Start(fun inbox-> 
    // the message processing function
    let rec messageLoop() = async{
        try
            // read a message
            let! msg = inbox.Receive 30000
            // process a message
            match msg with
            | Message text ->
                sw.WriteLine("{0}: {1}", DateTime.UtcNow.ToShortTimeString(), text)
                printfn "%s" text
                // loop to top
                return! messageLoop()  
            | Shutdown replyChannel ->
                replyChannel.Reply()
                // We do NOT do return! messageLoop() here
        with 
        | exc -> 
            printfn "%s" exc.Message
        }
    // start the loop 
    messageLoop() 
    )

我可以看到控制台中打印的超时消息,但程序永远不会结束:我错过了什么?

这就是我printerAgent在代码中调用的方式

printerAgent.PostAndReply( (fun replyChannel -> Shutdown replyChannel), 10000)

请注意,inbox.Receive()它最终会在几分钟后正常终止,但我的目标是设置超时(例如 30 秒)。

4

1 回答 1

1

我想我看到了概念上的问题。在收到最终关闭消息之前,我无法终止消息循环(否则程序发送的所有以下消息将在队列printerAgent.Post中保持未处理状态,不会因任何错误阻塞程序,最终关闭消息由 a将超时,也不会因任何错误而阻塞程序)。我应该返回消息循环,以便它在超时后实际上可以继续,就像正常接收到的消息一样:printerAgent.PostAndReply

with 
| exc -> 
    printfn "%s" exc.Message
    return! messageLoop() // important! I guess I can't really terminate the message loop from here

此时程序同时终止:我只是Timeout of Mailbox.Receive在控制台中看到很多打印(在消息循环空闲等待接收消息时每 n=30 秒,因此它们可以提供有关经过时间的信息) .

于 2021-01-11T13:28:19.850 回答