F# 让我来!按顺序执行?
我的印象是,让!在f#中,他足够聪明,可以并行地执行赋值序列。 但是,下面的示例显示了不同的行为,a、b、c的赋值似乎是同步执行的F# 让我来!按顺序执行?,f#,async-workflow,F#,Async Workflow,我的印象是,让!在f#中,他足够聪明,可以并行地执行赋值序列。 但是,下面的示例显示了不同的行为,a、b、c的赋值似乎是同步执行的 let sleep sec = async { System.Threading.Thread.Sleep(sec * 1000) return sec } let bar = async
let sleep sec =
async
{
System.Threading.Thread.Sleep(sec * 1000)
return sec
}
let bar = async
{
let! a = sleep 1
let! b = sleep 3
let! c = sleep 3
return a+b+c
}
let foo = Async.RunSynchronously(bar)
printfn "%d" foo
是这样吗
如果我想并行执行a,b,c,我应该使用Async.parallel…|>Async.RunSynchronously。。。那么
上面的示例当然是无用的,真正的用例类似于查询数据库并同时调用一些Web服务。
let在async
块(或更准确地说是“计算表达式”)中,code>异步执行表达式,但块作为一个整体仍然线性执行。这就是async
计算表达式的好处:通过为您执行连续传递,使相关异步操作序列更易于编写
(其他类型的计算表达式为let!
、yield!
等提供了自己的语义。)
要执行并行/并发执行,需要分别执行多个async
表达式
我有这样的印象
您误解了(这是可以理解的)。正如Richard指出的,异步工作流仍然是完全顺序的。我不认为任何尝试进行全自动并行化的项目都是完全成功的,因为这样做太困难了
但是,异步工作流仍然使并行化更容易。关键是,它们可以在不阻塞线程的情况下进行等待(这对于可伸缩性至关重要),并且还支持自动取消和简单的异常处理,使您的生活更轻松。有多种模式允许您在异步工作流中并行化代码
- 基于任务的您可以在后台启动三项任务,然后等待它们全部完成(这可能是您所期望的,下面是如何明确编写):
- 数据并行-如果您有多个相同类型的工作流,则可以使用
Async.parallel
创建一个并行运行所有工作流的工作流。然后使用let代码>它运行所有三个任务并等待它们完成:
let bar = async {
let! all = Async.Parallel [ sleep 1; sleep 3; sleep 3 ]
return all.[0] + all.[1] + all.[2] }
Don Syme有一篇文章讨论了基于异步工作流的问题,你可以在Async中找到一个全面的例子。StartAsChild
应该是Async。StartChild
,我相信。@wmeyer:是的,你是对的-谢谢你的更正,我修正了答案。
let bar = async {
let! all = Async.Parallel [ sleep 1; sleep 3; sleep 3 ]
return all.[0] + all.[1] + all.[2] }