【发布时间】:2011-04-19 08:02:01
【问题描述】:
我刚刚花了很长时间才弄清楚为什么这段代码对于某些网址“挂起”:
let getImage (imageUrl:string) =
async {
try
let req = WebRequest.Create(imageUrl) :?> HttpWebRequest
req.UserAgent <- "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1; .NET CLR 1.1.4322)";
req.Method <- "GET";
req.AllowAutoRedirect <- true;
req.MaximumAutomaticRedirections <- 4;
req.Timeout <- 3000; //HAHAHA, nice try!
let! response1 = req.AsyncGetResponse()
let response = response1 :?> HttpWebResponse
use stream = response.GetResponseStream()
let ms = new MemoryStream()
let bytesRead = ref 1
let buffer = Array.create 0x1000 0uy
while !bytesRead > 0 do
bytesRead := stream.Read(buffer, 0, buffer.Length)
ms.Write(buffer, 0, !bytesRead)
return SuccessfulDownload(imageUrl, ms.ToArray())
with
ex -> return FailedDownload(imageUrl, ex.Message)
}
在设法追踪 3000 个 URL 中的哪个被挂起后,我了解到 AsyncGetResponse 没有注意到 HttpWebRequest.Timeout。我做了一些搜索,提出了将异步请求包装在带有计时器的线程中的建议。这对 C# 来说很棒,但如果我通过 Async.Parallel |> Async.RunSynchronously 运行其中的 3000 个,那么处理这个问题的最佳方法是什么?
【问题讨论】:
-
您应该只使用
stream.CopyTo ms而不是使用buffer和bytesRead进行所有手动复制。 -
@ildjarn,感谢您的信息,我不得不承认这是来自here的直接复制粘贴
标签: asynchronous f# httpwebrequest