我预计这段代码会在 1 秒后崩溃,但它永远不会终止。
open System
open System.Threading.Tasks
let foo () =
task {
do! Task.Delay(1_000_000)
return 1
}
let bar () =
task {
do! Task.Delay(1_000)
raise (Exception "KABOOM")
return 3
}
let main () =
task {
do! Task.Delay(100)
let! results = Task.WhenAll(foo (), bar ())
return Seq.sum results
}
main ()
|> fun t -> t.Result
|> printfn "%i"
Task.WhenAll
的行为如预期?它确实会因异常而终止,只有在 1000 秒后 - 当
foo
终止时。这就是 Task.WhenAll
的工作原理,我没有找到解决办法。
如果将
task
替换为 async
(将 Task.WhenAll
替换为 Async.Parallel
,将 t.Result
替换为 Async.RunSynchronously
),则行为将完全符合您的预期。
F# Async 优于 C# Task 的另一个原因。