I am trying to use this as a commonly accepted solution for setting a timeouts for WeblClient calls. In my test case of requesting a url from an offline machine: I consistently get 20 second timeouts when set at 1 second.
public class TimeoutWebClient : WebClient
{
public TimeoutWebClient(TimeSpan timeout)
{
_timeout = timeout;
}
private TimeSpan _timeout;
protected override WebRequest GetWebRequest(Uri address)
{
WebRequest request = base.GetWebRequest(address);
request.Timeout = (int)_timeout.TotalMilliseconds;
return request;
}
}
Server based timeouts can't matter in this scenario. What could I be missing?
I did find a snippet that set both HttpWebRequest.ReadWriteTimeout and HttpWebRequest.ServicePoint.MaxIdleTime. But setting these to the timeout value still didn't make a difference and am still getting ~20 second timeouts.
Any other thoughts of what could cause this behavior?
Any chance you are using async download method?
From the MSDN:
The Timeout property affects only synchronous requests made with the GetResponse method. To time out asynchronous requests, use the Abort method.
Related
I am struggling to achieve a requirement from the client.
I have a web service which in turn invokes client's webservice. Our service POST a request to the client service using UploadString() property of webclient.Here I have frequent requests to the client service,so I would like to keep the connection alive.I came to know that in HTTP 1.1 there is a feature called "KeepAlive" which allows persistent connection.My question is, is it possible to configure the timeout property of this keepalive via c# code?
Appreciate your help:)
To use that method, you must create a class derived from WebClient, see this example. You can set timeout, keepalive, tcpkeepalive also there. And use this class, instead of WebClient:
public class WebClientExtended : WebClient
{
protected override WebRequest GetWebRequest(Uri uri)
{
var w = (HttpWebRequest) base.GetWebRequest(uri);
w.Timeout = 5000; // Set timeout
w.KeepAlive = true; // Set keepalive true or false
w.ServicePoint.SetTcpKeepAlive(true, 1000, 5000); // Set tcp keepalive
return w;
}
}
I currently have a python server running that handles many different kinds of requests and I'm trying to do this using C#. My code is as follows:
try
{
ServicePointManager.DefaultConnectionLimit = 10;
System.Net.ServicePointManager.Expect100Continue = false;
HttpWebRequest request = (HttpWebRequest)WebRequest.Create(url);
request.Proxy = null;
request.Method = "GET";
using (HttpWebResponse response = (HttpWebResponse)request.GetResponse())
{
response.Close();
}
}
catch (WebException e)
{
Console.WriteLine(e);
}
My first get request is almost instant but after that, the time it takes for one request to go through is almost 30 seconds to 1 min. I have researched everywhere online and tried to change the settings to make it run faster but it can't seem to work. Are there anymore settings that I could change to make it faster?
By using my psychic debugging skills I guess your server only accepts one connection at the time. You do not close your request, so you connection is kept alive. Keep alive attribute. The server will accept new connection when you current one is closed, which is default 100000ms or the server timeout. In your case I guess 30 to 60 seconds. You can start by setting the keepalive attribe to false.
I have some logic issues with HttpWebRequest class.
I using HttpWebRequest class from System.Net namespace, and when I doing this:
while(true)
{
HttpWebRequest request = WebRequest.Create("http://somesite.com/") as HttpWebRequest;
HttpWebResponse responce = request.GetResponse() as HttpWebResponse;
}
I get response one by one with overage one sec interval, but I think my internet connection can work faster because the received data is very small. Then I try this:
while(true)
{
HttpWebRequest request = WebRequest.Create("http://google.com/") as HttpWebRequest;
HttpWebResponse response = request.BeginGetResponse(EndReceive, obj);
}
internal void EndReceive(IAsyncResult ar)
{
obj.Response = obj.Request.EndGetResponse(ar) as HttpWebResponse;
}
And I get very small speed increasing, something about 10-30%, but I use async request, I send to server 5 request instead of one, why speed wasn't increase by more than 100%?
It's ok if server can't handle more than one request from one ip at the same time... But when I run 10 console app with code:
void SendRequest()
{
HttpWebRequest request = WebRequest.Create("http://google.com/") as HttpWebRequest;
HttpWebResponse responce = request.BeginGetResponse(EndReceive, obj);
}
void EndReceive(IAsyncResult ar)
{
obj.Response = obj.Request.EndGetResponse(ar) as HttpWebResponse;
}
I get speed increasing for like 4-8 times, is problem with HttpWebRequest class? And why i cant get such speed with one application but many async requests?
I strongly suspect you're basically being bounded by the built-in connection pool, which will limit the number of requests a single process (or possibly AppDomain) makes to a given host. If you want to change the number of concurrent requests you can make to a single host, use the <connectionManagement> element in your app.config.
As an aside, you should have a using statement when you use the response, otherwise you're not disposing of it properly... which can cause horrible problems with the connection pool in itself.
If the website isn't responding after one second or so, it's probably safe to assume that it's a bad link and that I should move on to my next link in a set of "possible links."
How do I tell the WebClient to stop attempting to download after some predetermined amount of time?
I suppose I could use a thread, but if it's taking longer than one second to download, that's ok. I just want to make sure that it's connecting with the site.
Perhaps I should modify the WebClient headers, but I don't see what I should modify.
Perhaps I should use some other class in the System.Net namespace?
If you use the System.Net.WebRequest class you can set the Timeout property to be short and handle timeout exceptions.
try{
var request = WebRequest.Create("http://www.contoso.com");
request.Timeout = 5000; //set the timeout to 5 seconds
request.Method = "GET";
var response = request.GetResponse();
}
catch(WebException webEx){
//there was an error, likely a timeout, try another link here
}
We will need to call out to a 3rd party to retrieve a value using REST, however if we do not receive a response within 10ms, I want to use a default value and continue processing.
I'm leaning towards using an asynchronous WebRequest do to this, but I was wondering if there was a trick to doing it using a synchronous request.
Any advice?
If you are doing a request and waiting on it to return I'd say stay synchronous - there's no reason to do an async request if you're not going to do anything or stay responsive while waiting.
For a sync call:
WebRequest request = WebRequest.Create("http://something.somewhere/url");
WebResponse response = null;
request.Timeout = 10000; // 10 second timeout
try
{
response = request.GetResponse();
}
catch(WebException e)
{
if( e.Status == WebExceptionStatus.Timeout)
{
//something
}
}
If doing async:
You will have to call Abort() on the request object - you'll need to check the timeout yourself, there's no built-in way to enforce a hard timeout.
You could encapsulate your call to the 3rd party in a WebService. You could then call this WebService synchronously from your application - the web service reference has a simple timeout property that you can set to 10 seconds or whatever.
Your call to get the 3rd party data from your WebService will throw a WebException after the timeout period has elapsed. You catch it and use a default value instead.
EDIT: Philip's response above is better. RIF.