我有以下代码
open FSharp.Data
let downloadFile link =
......
use os = File.Create(...)
Http.RequestStream(....).ReponseStream.CopyTo(os)
let rec consume() = async {
......
|> Seq.iter (fun x ->
xxx |> Seq.iter(fun link ->
downloadFile link
))
}
我发现同步下载导致代码无法并发运行。所以我正在尝试执行以下操作。如何更改它以使用 FSharp.Data http AsyncRequestStream
?也许 CopyTo
也可以是异步的?
open FSharp.Data
let downloadFile link = async {
......
use os = File.Create(...)
Http.AsyncRequestStream(....).ReponseStream.CopyTo(os) // Error
}
let rec consume() = async {
......
|> Seq.iter (fun x ->
xxx |> Seq.iter(fun link ->
downloadFile link |> Async.Start // do! downloadFile link????
))
}
consume() |> Async.RunSynchronously
最佳答案
这是一个框架解决方案,值得您示例中的所有空白点:
let downloadFile link =
async {
......
use os = File.Create(...)
let! resp = Http.AsyncRequestStream(....)
return resp.ReponseStream.CopyTo(os)
}
let consume link =
async {
let comps : Async<unit> [] =
xxx
|> Seq.map (fun link -> downloadFile link)
|> Array.ofSeq
return! Async.Parallel comps
}
我认为您应该继续阅读 asynchronicity and concurrency in general ,以及 how to use it in F# in particular .从 OP 看来,整个事情对你来说有点模糊。
编辑:回答评论中的问题:
使用return!
(或let!
,或do!
)异步执行嵌套工作流,然后继续执行当前工作流从那时起。也就是说,do!
“之下”的所有内容都被放入一个延续中,一旦 do!
“之后”的事物完成,该延续就会被调用。
而 Async.Start
在(另一个)后台线程上启动工作流并立即返回,而无需等待它完成。
关于f# - 如何将下载程序转换为异步?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38403635/