使用异步工作流并行化的最佳实践

Jul*_*iet 8 f# asynchronous async-workflow

让我们说我想刮一个网页,并提取一些数据.我最有可能写这样的东西:

let getAllHyperlinks(url:string) =
    async {  let req = WebRequest.Create(url)
             let! rsp = req.GetResponseAsync()
             use stream = rsp.GetResponseStream()             // depends on rsp
             use reader = new System.IO.StreamReader(stream)  // depends on stream
             let! data = reader.AsyncReadToEnd()              // depends on reader
             return extractAllUrls(data) }                    // depends on data
Run Code Online (Sandbox Code Playgroud)

let!讲述F#在另一个线程来执行代码,然后将结果结合到一个变量,并继续处理.上面的示例使用两个let语句:一个用于获取响应,一个用于读取所有数据,因此它至少生成两个线程(如果我错了,请纠正我).

虽然上面的工作流程会产生多个线程,但执行顺序是串行的,因为工作流程中的每个项目都依赖于前一个项目.在其他线程返回之前,无法在工作流程中进一步评估任何项目.

let!在上面的代码中有多个有什么好处?

如果没有,该代码如何更改以利用多个let!语句?

Bri*_*ian 9

关键是我们不会产生任何新线程.在整个工作流程中,ThreadPool消耗了1或0个活动线程.(例外,直到第一个'!',代码在执行Async.Run的用户线程上运行.)"let!" 当Async操作在海上时,让我们离开一个线程,然后在操作返回时从ThreadPool中获取一个线程.(性能)优势是对ThreadPool的压力较小(当然主要的用户优势是简单的编程模型 - 比您编写的所有BeginFoo/EndFoo /回调内容要好一百万倍).

另见http://cs.hubfs.net/forums/thread/8262.aspx