F#无法捕捉TimeoutException异常(F# can't catch Timeou

2019-10-21 03:10发布

我的问题是非常简单的。 请看看截图:

怎么可能发生呢? 我明确提出来电Async.RunSyncronously进入try ... with

Answer 1:

try/with F#中的异步工作流程不直接映射到CLR保护块-相反,如果异常在用户代码中提出,库中的代码将捕捉到它并重新路由到最近的错误延续(可即with blockfinally block ,在提供自定义错误延续Async.StartWithContinuations等)。 这有一个后果是,可能调试有关用户代码未处理的异常可以在以后处理和加工情况。

下面摘录报道在调试器中的类似错误但仍然执行成功完成

let error (): int = raise (System.TimeoutException())

let run() = async {
    try 
        let result = error()
        return result
    with
    :? System.TimeoutException -> return -1
}

let r = Async.RunSynchronously (run())
printfn "%d" r


Answer 2:

尝试这个:

let withTimeout (timeOut: option<int>) (operation: Async<'x>) : Async<option<'x>> =
  match timeOut with
   | None -> async {
       let! result = operation
       return Some result
     }
   | Some timeOut -> async {
       let! child = Async.StartChild (operation, timeOut)
       try
         let! result = child
         return Some result
       with :? System.TimeoutException ->
         return None
     }

你不应该使用Async.RunSynchronouslyasync块,因为这样做使得次优利用本地线程,并可能导致堆栈溢出 。 Async.RunSynchronously是用于运行Async从这样的计算以外的运算。 在一个async块,你可以使用普通let!do! 或者,例如, Async.StartChild运行Async计算。 这使得更有效地利用本地线程的,并且不会有潜在的堆栈溢出类似的问题困扰。



文章来源: F# can't catch TimeoutException