Asynchronous F#:异步下载数据
我是编程新手,F#是我的第一语言 以下是我的代码的相关部分:Asynchronous F#:异步下载数据,asynchronous,f#,Asynchronous,F#,我是编程新手,F#是我的第一语言 以下是我的代码的相关部分: open System.IO open System.Net let downloadHtmlFromUrlAsync (url: string) = async { let uri = new System.Uri(url) let webClient = new WebClient() let! html = webClient.AsyncDownloadString(u
open System.IO
open System.Net
let downloadHtmlFromUrlAsync (url: string) =
async {
let uri = new System.Uri(url)
let webClient = new WebClient()
let! html = webClient.AsyncDownloadString(uri)
return html
}
let downloadHtmlToDisk (url: string) (directoryPath: string) =
if isValidUrl url then
let name = getNameFromRedirectedUrl url
let id = getIdFromUrl url
let html = downloadHtmlFromUrlAsync url
let newTextFile = File.Create(directoryPath + "\\" + id.ToString("00000") + " " + name.TrimEnd([|' '|]) + ".html")
use file = new StreamWriter(newTextFile)
file.Write(html)
file.Close()
let downloadEntireDatabase (baseUrl: string) (totalNumberOfPeople: int) =
let allIds = [ for i in 1 .. totalNumberOfPeople -> i ]
allIds
|> Seq.map (fun id -> baseUrl + string(id))
|> Seq.filter isValidUrl
|> Seq.map downloadHtmlToDisk
|> Async.Parallel
|> Async.RunSynchronously
我在F#interactive中测试了函数isValidUrl、getNameFromRedirectedUrl和getIdFromUrl。他们工作得很好
我的问题是:当我尝试运行上面粘贴的代码时,会产生以下错误消息:
fs(483,8):错误FS0193:类型约束不匹配。类型
seq unit)>
与类型不兼容
seq
与类型string->unit
出了什么问题?我应该做哪些更改?问题可能是这一行(您能告诉我们下载FighterHTMLODisk的定义吗?):
根据错误消息,此函数似乎有签名
string->string->unit
,但您确实需要string->asynchwhere至少是:downloadfightrhtmltodisk
?谢谢,卡斯滕。我有一个后续问题:当我调用Async.Parallel时,如何指定要使用的最大线程数?您不能直接-基本上您必须将工作分组到所需的块中,并将其传递给Async.Parallel-或信任线程池;)
allIds
...
|> Seq.map downloadFighterHtmlToDisk
...
let downloadHtmlToDisk (directoryPath: string) (url: string) =
async {
if isValidUrl url then
let name = getNameFromRedirectedUrl url
let id = getIdFromUrl url
let! html = downloadHtmlFromUrlAsync url
let newTextFile = File.Create(directoryPath + "\\" + id.ToString("00000") + " " + name.TrimEnd([|' '|]) + ".html")
use file = new StreamWriter(newTextFile)
file.Write(html)
}
let downloadEntireDatabase (baseUrl: string) (totalNumberOfPeople: int) =
let allIds = [ for i in 1 .. totalNumberOfPeople -> i ]
allIds
|> Seq.map (fun id -> (id, baseUrl + string(id)))
|> Seq.filter (fun (_,url) -> isValidUrl url)
|> Seq.map (fun (id,url) -> downloadHtmlToDisk (getFighterPath id) url)
|> Async.Parallel
|> Async.RunSynchronously