是否有任何原语构成async1 然后 async2,类似于并行执行规划的并行功能?
进一步澄清,我有2个异步计算
let toto1 = Async.Sleep(1000)
let toto2 = Async.Sleep(1000)
我想创建一个由toto1和toto2的顺序组合构成的新异步计算
let toto = Async.Sequential [|toto1; toto2|]
一旦开始,toto将运行toto1然后toto2,并将在2000个时间单位后结束
答案 0 :(得分:4)
async.Bind
操作是异步工作流为顺序组合提供的基本原语 - 在async
块语法中,与let!
对应。您可以使用它来表示两个计算的顺序组合(如Daniel所示)。
但是,如果你有一个丹尼尔定义的操作<|>
,那么它的表达力不足以实现async.Bind
,因为当你使用async.Bind
顺序编写事物时,第二个计算可能取决于关于第一个的结果。 <e2>
可能会使用v1
:
async.Bind(<e1>, fun v1 -> <e2>)
如果您正在撰写<e1> <|> <e2>
,那么这两项操作必须是独立的。这就是为什么这些库基于Bind
的原因 - 因为它是顺序组合的表现形式,而不是你遵循Async.Parallel
结构时所获得的那种。
如果你想要一些行为类似于Async.Parallel
并采用数组的东西,那么最简单的选择是在循环中使用let!
强制实现(但你也可以使用递归和列表):< / p>
let Sequential (ops:Async<'T>[]) = async {
let res = Array.zeroCreate ops.Length
for i in 0 .. ops.Length - 1 do
let! value = ops.[i]
res.[i] <- value
return res }
答案 1 :(得分:2)
我不确定“原始”是什么意思。 Async.Parallel
是一个功能。以下是运行两个异步的几种方法:
同时:
Async.Parallel([|async1; async2|])
或
async {
let! child = Async.StartChild async2
let! result1 = child
let! result2 = async1
return [|result1; result2|]
}
顺序地:
async {
let! result1 = async1
let! result2 = async2
return [|result1; result2|]
}
你可以在最后两个中返回元组。我保持返回类型与第一个相同。
我会说let!
do!
和async { }
块中的let (<|>) async1 async2 =
async {
let! r1 = async1
let! r2 = async2
return r1, r2
}
尽可能接近使用原语。
如果有这些讨厌的语法,你可以定义一个组合器:
async1 <|> async2 |> Async.RunSynchronously
然后执行:
{{1}}