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