我不知道,为什么MailboxProcessor
的默认处理异常的策略只是他们默默地忽略了。例如:邮箱处理器和例外
let counter =
MailboxProcessor.Start(fun inbox ->
let rec loop() =
async { printfn "waiting for data..."
let! data = inbox.Receive()
failwith "fail" // simulate throwing of an exception
printfn "Got: %d" data
return! loop()
}
loop())
()
counter.Post(42)
counter.Post(43)
counter.Post(44)
Async.Sleep 1000 |> Async.RunSynchronously
并没有任何反应。没有致命的停止程序执行,或者出现带有“未处理的异常”的消息框。没有。
如果有人使用PostAndReply
方法,那么这种情况会变得更糟:结果是保证了死锁。
这种行为的任何原因?
是的,当然可以实施。我不明白,为什么* default *行为如此无语。例如,如果在'MailboxProcessor.add_Error'中没有处理程序,它可以重新抛出异常。 调试Async/multithreaded代码很困难。为什么我们应该更加努力完成这项任务? – qehgt
您可以争辩说,如果没有附加处理程序,最好取消进程(未处理的异常)。我不记得理由。 – Brian
重新抛出异常的一个问题是,你失去了堆栈跟踪 - 例如'async {failwith“bad”}'给出了一个堆栈跟踪深入F#libs,这可能是恼人的调试 - 显然这是一个.NET限制在不同的线程上重新抛出异常 –