本文介绍了如何处理HttpWebRequest的超时在F#Async.Parallel的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我只花了很长的时间打破为什么code是'挂'我的牙齿对某些网址:

I just spent a long time breaking my teeth on why this code was 'hanging' for some urls:

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网址被挂的,我了解到, AsyncGetResponse 不采取 HttpWebRequest.Timeout 。我已经做了一些搜索它抛出了包裹在一个带有计时器的线程异步请求的建议。这是伟大的C#,但如果我跑这些通过3000 Async.Parallel |&GT; Async.RunSynchronously ,什么是处理这个问题的最好方法是什么?

After managing to track down which of the 3000 urls was hanging, I learned that AsyncGetResponse doesn't take any notice of HttpWebRequest.Timeout. I've done a bit of searching which throws up suggestions of wrapping the async request in a thread with a timer. That's great for C#, but if I'm running 3000 of these through Async.Parallel |> Async.RunSynchronously, what's the best way to handle this problem?

推荐答案

我只粗略地测试过这一点,但它应该有正确的行为:

I've only roughly tested this, but it should have the correct behavior:

type System.Net.WebRequest with
  member req.AsyncGetResponseWithTimeout () =
    let impl = async {
      let iar = req.BeginGetResponse (null, null)
      let! success = Async.AwaitIAsyncResult (iar, req.Timeout)
      return if success then req.EndGetResponse iar
             else req.Abort ()
                  raise (System.Net.WebException "The operation has timed out") }
    Async.TryCancelled (impl, fun _ -> req.Abort ())

在您的code,叫 req.AsyncGetResponseWithTimeout()而不是 req.AsyncGetResponse的()

In your code, call req.AsyncGetResponseWithTimeout() instead of req.AsyncGetResponse().

这篇关于如何处理HttpWebRequest的超时在F#Async.Parallel的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

09-24 22:29