首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >MailboxProcessor与例外

MailboxProcessor与例外
EN

Stack Overflow用户
提问于 2012-05-29 18:58:24
回答 2查看 1.7K关注 0票数 18

我想知道,为什么MailboxProcessor处理异常的默认策略只是默默地忽略它们。例如:

代码语言:javascript
复制
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方法,这种情况会变得更糟:结果是一个有保证的死锁。

有这种行为的原因吗?

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2012-05-29 19:58:01

我认为,MailboxProcessor in F#不包含任何处理异常的机制的原因是,不清楚什么是最好的方法。例如,您可能希望在发生未处理异常时触发一个全局事件,但您可能希望在下一次调用PostPostAndReply时重新抛出异常。

这两个选项都可以基于标准的MailboxProcessor实现,因此可以添加所需的行为。例如,下面的代码片段显示了添加全局异常处理程序的HandlingMailbox。它具有与普通MailboxProcessor相同的接口(我省略了一些方法),但它添加了在发生异常时触发的OnError事件:

代码语言:javascript
复制
type HandlingMailbox<'T> private(f:HandlingMailbox<'T> -> Async<unit>) as self =
  let event = Event<_>()
  let inbox = new MailboxProcessor<_>(fun inbox -> async {
    try 
      return! f self
    with e ->
      event.Trigger(e) })
  member x.OnError = event.Publish
  member x.Start() = inbox.Start()
  member x.Receive() = inbox.Receive()
  member x.Post(v:'T) = inbox.Post(v)
  static member Start(f) =
    let mbox = new HandlingMailbox<_>(f)
    mbox.Start()
    mbox

要使用它,您可以编写与之前编写的代码相同的代码,但现在可以异步处理异常:

代码语言:javascript
复制
let counter = HandlingMailbox<_>.Start(fun inbox -> async {
  while true do 
    printfn "waiting for data..." 
    let! data = inbox.Receive() 
    failwith "fail" })

counter.OnError.Add(printfn "Exception: %A")
counter.Post(42) 
票数 6
EN

Stack Overflow用户

发布于 2012-05-29 20:24:25

Error上有一个MailboxProcessor事件。

http://msdn.microsoft.com/en-us/library/ee340481

代码语言:javascript
复制
counter.Error.Add(fun e -> printfn "%A" e)

当然,如果你想控制自己,你可以做一些类似Tomas的解决方案。

票数 16
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/10805035

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档