namespace HttpWebRequest_HighIntesive
using System.Diagnostics;
public int RequestsCount { get; private set; }
public CountdownEvent CountdownEvent { get; private set; }
public ThreadParam(int requestsCount, CountdownEvent countdownEvent)
RequestsCount = requestsCount;
CountdownEvent = countdownEvent;
public CountdownEvent CountdownEvent { get; private set; }
public HttpWebRequest HttpWebRequest { get; private set; }
public FinistRequestParam(CountdownEvent countdownEvent, HttpWebRequest httpWebRequest)
CountdownEvent = countdownEvent;
HttpWebRequest = httpWebRequest;
static volatile int _numberOfFinishedRequests;
static double _prevMemoryMb = 0;
public static int Main(string[] args)
Console.Write("Enter URL(full format, for example, http://google.ru): ");
var url = Console.ReadLine();
if (!Uri.TryCreate(url, UriKind.RelativeOrAbsolute, out _uri)){
Console.WriteLine("Invalid URL. Exiting"); return -1;
Console.Write("Enter number of requests: ");
numOfRequests = Int32.Parse(Console.ReadLine());
DoParallelRequests(numOfRequests);
Console.WriteLine("Finished. Press 'Enter' to quit");
private static void DoParallelRequests(int numOfRequests)
System.Net.ServicePointManager.DefaultConnectionLimit = 350;
Console.WriteLine("DefaultConnectionLimit: {0}", System.Net.ServicePointManager.DefaultConnectionLimit);
int threadCnt = Environment.ProcessorCount;
Console.WriteLine("Num of threads which creates HttpWebRequest: {0}", threadCnt);
CountdownEvent countDownOnTimes = new CountdownEvent(numOfRequests);
using (var timer = new Timer(TimerStatisticHanlder, Stopwatch.StartNew(), TimeSpan.FromSeconds(2), TimeSpan.FromSeconds(5)))
Thread[] threads = new Thread[threadCnt];
for (int i = 0; i < threads.Length; i++)
threads[i] = new Thread(ThreadMethod);
threads[i].Start(new ThreadParam(numOfRequests / threadCnt, countDownOnTimes));
static void TimerStatisticHanlder(object obj)
Stopwatch sw = obj as Stopwatch;
var aveageSpeed = Math.Round(_numberOfFinishedRequests / sw.Elapsed.TotalSeconds, 2);
var totalMemoryMb = Math.Round((double)GC.GetTotalMemory(false) / 1024 / 1024);
var memoryDeltaMb = totalMemoryMb - _prevMemoryMb;
Console.WriteLine("{0} Processed requests: {1}, Average speed: {2} requests per/s, Used memory: {3} Mbytes, Memory delta: {4}", DateTime.Now.ToString("HH:mm:ss"), _numberOfFinishedRequests, aveageSpeed, totalMemoryMb, memoryDeltaMb);
_prevMemoryMb = totalMemoryMb;
private static void ThreadMethod(object state)
var threadParam = state as ThreadParam;
for (int i = 0; i <= threadParam.RequestsCount; i++)
HttpWebRequest request = (HttpWebRequest)WebRequest.Create(_uri);
request.BeginGetResponse(new AsyncCallback(FinishRequest), new FinistRequestParam(threadParam.CountdownEvent, request));
private static void FinishRequest(IAsyncResult result)
var reqParam = result.AsyncState as FinistRequestParam;
var request = reqParam.HttpWebRequest;
HttpWebResponse response = request.EndGetResponse(result) as HttpWebResponse;
response.GetResponseStream().Dispose();
(request as IDisposable).Dispose();
reqParam.CountdownEvent.Signal();
Interlocked.Increment(ref _numberOfFinishedRequests);