等待GET回复

时间:2012-05-02 21:10:42

标签: c# proxy httpwebrequest proxies

我遇到问题,我的代码会等待很长一段时间 HttpWebResponse response = (HttpWebResponse)request.GetResponse();我做错了什么?有时我从队列中得到不好的代理,所以我希望能够超时并跳过。

        Boolean match = false;
        String clean = String.Empty;
        String msbuff;
        IWebProxy insideProxy;
        try
        {
            //grab proxies based on queue
            String proxyQueItem = Proxy_Que(_rankingConnectionString);
            insideProxy = new WebProxy(proxyQueItem);

            HttpWebRequest request = (HttpWebRequest) WebRequest.Create(ResultURL);
            request.Proxy = insideProxy;
            request.Timeout = 15*1000;

            using (HttpWebResponse response = (HttpWebResponse) request.GetResponse())
            {
                if (response.StatusCode == HttpStatusCode.OK)
                {
                    Stream streamResponse = response.GetResponseStream();
                    StreamReader streamRead = new StreamReader(streamResponse);
                    msbuff = streamRead.ReadToEnd();
                    //get rid of , -, (, )
                    msbuff = msbuff.Replace(" ", String.Empty).Replace(" ", String.Empty);
                    msbuff = msbuff.Replace("-", String.Empty);
                    msbuff = msbuff.Replace("(", String.Empty);
                    msbuff = msbuff.Replace(")", String.Empty);
                    //attempt to find phone number
                    match = msbuff.Contains(Listing.PhoneNumber);
                    streamRead.Close();
                }

            }
        }
        catch (Exception lk)
        { }

4 个答案:

答案 0 :(得分:2)

我遇到了同样的问题。问题出在你的超时代码上。你有:

request.Timeout = 15*1000;

你需要:

request.Timeout = 15*1000;
request.ReadWriteTimeout = 15*1000;

.Timeout属性用于发送的超时。但是,在发送请求并开始读取之后,请求的总体超时。它是通过ReadWriteTimeout属性设置的。

ReadWriteTimeout的默认值是5分钟,这就是为什么你会看到你所看到的行为。

答案 1 :(得分:1)

由于您指定了15秒的超时时间,我假设您等待的时间超过15秒。代码延迟的原因可能是它正在等待连接变得可用。等待连接所花费的时间与请求的超时无关。

我相信默认情况下,.NET只允许两个同时连接到“端点”(IP地址)。这可以通过您的app / web配置进行配置:

<system.net>
  <connectionManagement>
    <add address="www.example.com" maxconnection="10"/>
  </connectionManagement>
</system.net>

但是,这可能无法解决问题,因为与之通信的服务器可能只允许每个客户端有限数量的连接。您的代理人也可能参与其中。

答案 2 :(得分:1)

之前我遇到过这个问题并且对超时设置进行了简单的更改修复了它。这是VB.NET而不是C#,但你应该能够搞清楚。首先,指定可以线程化的第二个超时方法:

Private Sub TimeoutCallback(ByVal state As Object, ByVal timedOut As Boolean)
        If timedOut Then
            Dim request As Net.HttpWebRequest = state
            If Not (request Is Nothing) Then
                request.Abort()
            End If
        End If
    End Sub

然后,当您构建请求并回读时,您可以设置如下内容:

Try
            Dim myHttpWebRequest1 As Net.HttpWebRequest
            ' Create a new HttpWebrequest object to the desired URL.
            myHttpWebRequest1 = CType(WebRequest.Create(String.Format("http://{0}:{1}", inURL, inPORT)), Net.HttpWebRequest)

            ' Create an instance of the RequestState and assign the previous myHttpWebRequest1
            ' object to it's request field.  
            Dim myRequestState As New RequestState()
            myRequestState.request = myHttpWebRequest1
            ' Start the Asynchronous request.
            allDone.Reset()
            Dim result As IAsyncResult = CType(myHttpWebRequest1.BeginGetResponse(AddressOf RespCallback, myRequestState),  _
                                               IAsyncResult)
            ThreadPool.RegisterWaitForSingleObject(result.AsyncWaitHandle, _
                                                   New WaitOrTimerCallback(AddressOf TimeoutCallback), _
                                                   myHttpWebRequest1, DefaultTimeout, True)
            allDone.WaitOne()

注意TheadPool行(从下面开始的第2行),它将在单独的线程上提交您的超时方法,这样即使您的其他请求由于无效的IP地址或主机而挂起,它也可以取消请求。

答案 3 :(得分:0)

如果你有一个代理队列,你只需要超时并跳转到下一个,如果它是坏的,那么你可以循环直到你得到一个响应,捕获错误并每次从队列中获取一个新的代理通过。像这样......

private string requestByProxy(string url)
{
    string responseString, proxyAddress;

    while (responseString == null)
    {
        try
        {
            HttpWebRequest request = (HttpWebRequest)WebRequest.Create(url);
            // set properties, headers, etc

            proxyAddress = getNextProxy();

            if (proxyAddress == null)
                throw new Exception("No more proxies");

            request.Proxy = new WebProxy(proxyAddress);
            request.Timeout = 15 * 1000;

            HttpWebResponse response = (HttpWebResponse)request.GetResponse();
            StreamReader sr = new StreamReader(response.GetResponseStream());
            responseString = sr.ReadToEnd();
        }
        catch (WebException wex)
        {
            continue;
        }
    }

    return responseString;
}