让我们说我想刮一个网页,并提取一些数据.我最有可能写这样的东西:
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
的let!
讲述F#在另一个线程来执行代码,然后将结果结合到一个变量,并继续处理.上面的示例使用两个let语句:一个用于获取响应,一个用于读取所有数据,因此它至少生成两个线程(如果我错了,请纠正我).
虽然上面的工作流程会产生多个线程,但执行顺序是串行的,因为工作流程中的每个项目都依赖于前一个项目.在其他线程返回之前,无法在工作流程中进一步评估任何项目.
let!
在上面的代码中有多个有什么好处?
如果没有,该代码如何更改以利用多个let!
语句?
关键是我们不会产生任何新线程.在整个工作流程中,ThreadPool消耗了1或0个活动线程.(例外,直到第一个'!',代码在执行Async.Run的用户线程上运行.)"let!" 当Async操作在海上时,让我们离开一个线程,然后在操作返回时从ThreadPool中获取一个线程.(性能)优势是对ThreadPool的压力较小(当然主要的用户优势是简单的编程模型 - 比您编写的所有BeginFoo/EndFoo /回调内容要好一百万倍).
另见http://cs.hubfs.net/forums/thread/8262.aspx