Dax*_*ohl 3 workflow f# asynchronous
(注意我正在谈论流水线操作,如并行运行独立进程;与|>运算符无关).
所以,如果我有两个功能
let incr x =
Thread.Sleep 1000
x + 1
let product x y =
Thread.Sleep 1000
x * y
Run Code Online (Sandbox Code Playgroud)
是否有一种简单的方法来编写像(伪代码)这样的工作流程
let productOfIncrements x y =
async {
let! x1 = incr x
let! y1 = incr y
let! result = product x1 y1
return result
}
Run Code Online (Sandbox Code Playgroud)
管道前两个独立的操作,因此在两秒钟内执行,或异步工作流程是否解决了这个问题?如果有一个很好的解决问题的方法,是否有一种直接的方法来扩展这样的方法,比如在N + 1秒而不是2N中进行递归因子计算?
最简单的选择是使用Async.StartChild.这个原始启动在后台(在线程池中)启动异步操作,并返回一个"令牌",可用于等待操作的完成.这不会阻止工作流,因此您可以继续运行其他操作:
let productOfIncrements x y =
async {
// Start the 'incr x' operation in background
let! x1Op = async {return incr x} |> Async.StartChild
// Continue doing other work
// (synchronously since it takes the same time as the above.)
let y1 = incr y
// Now wait for the result of 'incr x' (if it is still running)
let! x1 = x1Op
// return the product (just call the function synchronously)
return product x1 y1
}
Run Code Online (Sandbox Code Playgroud)
如果两个操作返回相同的类型,那么您也可以使用Async.Parallel,它组成多个操作并行运行.
如果您正在使用纯粹的CPU绑定计算并且需要创建大量计算,那么您也可以Tasks直接使用.NET (例如参见本文).任务更有效,但使用起来并不优雅(并且不支持异步等待).
作为旁注,通常使用术语管道(至少在F#或.NET世界中)用于更复杂的事情 - 例如,假设您有一系列相互依赖的步骤.处理多个输入时,您可以并行运行这些步骤(并且仍然限制总的并行度).这也可以使用F#异步工作流完成 - 例如参见本文.还有一个名为pipelets的框架实现了这个概念.