我有两个异步操作,所以我有这些功能:
let MyFunc = async {
let! person = GetPerson()
let! address = GetAddress()
...
}
并行执行它们并获得结果的惯用方法是什么?
我的出发点是这种方法。
let MyFunc = async {
let personA = GetPerson()
let addressA = GetAddress()
let! person = personA
let! address = addressA
...
}
这样可行,但这会按顺序运行两个操作。
我也试过这个(基于我的C#体验)。
Async.Parallel
但它不起作用,它也按顺序运行两个操作。
大多数文档说的是将let MyFunc = async {
let personA = GetPerson()
let addressA = GetAddress()
[personA; addressA]
|> Async.Parallel
...
}
与序列一起使用,但问题是两个操作的结果类型不同,所以我不能将它们放在一个序列中。
authorizeFromController:controller:openURL:browserAuth
这会产生编译错误,因为这两个值具有不同的类型。 (而且,使用这种语法,我怎样才能得到实际结果?)
这样做的惯用方法是什么?
答案 0 :(得分:8)
惯用法是使用Async.StartAsChild
启动两个计算,然后使用第二个let!
等待完成:
let MyFunc = async {
let! personWork = GetPerson() |> Async.StartChild
let! addressWork = GetAddress() |> Async.StartChild
let! person = personWork
let! address = addressWork
// (...)
}
只是调用GetPerson
实际上并没有开始工作 - 与在C#中创建任务的开始不同,F#工作流只是要完成工作的描述,因此需要明确启动它们。 Async.StartChild
操作为您提供了一个工作流,可以启动工作并返回另一个可用于等待其完成的工作流。