我遇到问题,我的代码会等待很长一段时间
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)
{ }
答案 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;
}