2

I am sending a large number of simultaneous requests to a particular web service with different data. To achieve this, I have created a number of threads(around 50 in number). Total number of requests per minute may increase up to 10000. The application in the form of a windows service runs fine for a few minutes and then a operation time out error is encountered.

I have tried the usual suspects such as increasing DefaultConnectionLimit, closing the web response object. Since the requests do not take much time on server, I have also set the request Timeout and ReadWriteTimeout to 5 seconds. Below is the code snippet which is called repeatedly by different threads.

// Below line is executed at the start of application
ServicePointManager.DefaultConnectionLimit = 15000;

// Below code is executed at repeatedly by different threads
HttpWebRequest request = (HttpWebRequest)HttpWebRequest.Create(url);
request.Host = hostName;
request.Proxy = null;
request.UserAgent = "Windows Service";
byte[] bytes = new byte[0];
if (body != null)
{
    bytes = System.Text.Encoding.ASCII.GetBytes(body);
    request.ContentType = "text/xml; encoding='utf-8'";
    request.ContentLength = bytes.Length;
}
request.Method = "POST";
request.Timeout = 5000;
request.ReadWriteTimeout = 5000;

request.Headers["Authorization"] = "Basic " + Convert.ToBase64String(Encoding.Default.GetBytes(username + ":" + password));

request.CookieContainer = this.cookieContainer;

if (body != null)
{
    Stream requestStream = request.GetRequestStream();
    requestStream.Write(bytes, 0, bytes.Length);
    requestStream.Close();
}

HttpWebResponse httpResponse = (HttpWebResponse)request.GetResponse();

using (var streamReader = new StreamReader(httpResponse.GetResponseStream()))
{
     responseText = streamReader.ReadToEnd();
}
httpResponse.Close();
pull420
  • 88
  • 2
  • 8
  • Are you using http 1.0 or 1.1? Try forcing to 1.0 : request.ProtocolVersion = HttpVersion.Version10; 1.1 is chunk mode and if you do not send next chunk message you will get a timout. – jdweng Feb 14 '18 at 11:13
  • @FaizanRabbani : -yes I tried to increase timeout but it just slows down subsequent requests and the error is logged after that timeout period. So, isn't really helping us. – pull420 Feb 14 '18 at 11:20
  • @FaizanRabbani :- No, its a windows service. – pull420 Feb 14 '18 at 11:23
  • Are you sure the problem is on your side? Perhaps the web service only (for example) services 3 requests at a time and queues the others? – mjwills Feb 14 '18 at 11:27
  • 1
    Can you try something this user suggested? https://stackoverflow.com/a/16744521/4222487 – FaizanHussainRabbani Feb 14 '18 at 11:32
  • I am not sending 15000 requests simultaneously, But is there any issue with setting this value to 15000 instead of 50? It still is more than the number of simultaneous requests. I see no documentation which says so. – pull420 Feb 14 '18 at 11:35
  • Does it improve if you set it to 50? Also please update your post to show how you are managing threading. Is it `Parallel.ForEach`? Something else? – mjwills Feb 14 '18 at 11:39
  • No not yet...... – pull420 Feb 21 '18 at 09:48

1 Answers1

5

ServicePointManager.DefaultConnectionLimit limits the number of outgoing web requests to a given server. The default is generally 2 or 10.

If you are making 50 parallel calls to that web service, you should set ServicePointManager.DefaultConnectionLimit (at app startup) to a larger number (e.g. 40-50).

Additionally, you are not calling Close or Dispose on request. You should do this, or let using take care of it for you.

mjwills
  • 23,389
  • 6
  • 40
  • 63
  • So, when you make more simultaneous request than the DefaultConnectionLimit , aren't requests just queued? Could you lose a request this way? – H H Mar 01 '19 at 12:55
  • Yes they are queued @HenkHolterman. But if you queue **enough** of them, some will start to timeout (as the OP mentions). Imagine doing 10,000 requests a minute, and each request takes 10 seconds. If you do only 10 requests at a time (default value of this setting for a web app), clearly your throughput is _effectively_ capped to 60 per minute. 9,940 of them will timeout. – mjwills Mar 01 '19 at 12:58