let failing = async {
failwith "foo"
}
let test () =
try
Async.Start(failing)
with
| exn -> printf "caught"
此代码没有捕获异常。如何在单独的线程上启动异步工作流并捕获主程序中的异常?
答案 0 :(得分:0)
由于没有等待的结果,因此没有可以捕获异常的地方。你需要包装计算。一种可能性:
let failing = async {
failwith "foo"
}
let test () =
async {
let! res = failing |> Async.Catch
match res with
| Choice1Of2 _ -> printf "success"
| Choice2Of2 exn -> printfn "failed with %s" exn.Message
} |> Async.Start
答案 1 :(得分:0)
作为替代方案,您可以将工作流作为任务启动,并使用它的方法和属性。例如,Task.Result
将再次重新抛出异常,因此这很有效,几乎是您尝试过的:
let test () =
try
Async.StartAsTask failing
|> fun t -> t.Result
with _ -> printfn "caught"
> test ();;
caught
val it : unit = ()
ContinueWith
(虽然有点难看):
open System.Threading.Tasks
let test () =
(Async.StartAsTask failing).ContinueWith(fun (t : Task<_>) -> try t.Result with _ -> printfn "caught")
> test ();;
caught
val it : Task = System.Threading.Tasks.Task {AsyncState = null;
CreationOptions = None;
Exception = null;
Id = 3;
IsCanceled = false;
IsCompleted = true;
IsFaulted = false;
Status = RanToCompletion;}
Async.Catch
你也不需要Async.Catch
:
let test () =
async {
try
do! failing
with _ -> printfn "caught"
} |> Async.Start