I have HTTP client which basically invokes multiple web requests against HTTP server. And I execute each HTTP request in a thread pool thread (synchronous call), and by default uses 30 TCP (using httpwebrequest.servicepoint - http://msdn.microsoft.com/en-us/library/system.net.httpwebrequest.servicepoint.aspx ). And based on the system i am managing, there can be ~500/1000 thread pool threads waiting for I/O (http response)
Now, I am wondering do I need to limit the number of threads I use as well? (for ex, http://msdn.microsoft.com/en-us/library/ee789351(v=vs.110).aspx System.Threading.Tasks - Limit the number of concurrent Tasks )
EDIT
Yes, I think I need to, limit the number of threads I use as even though these threads are in wait state they take up resources. This way I can control number of resources/threads I use up which makes it easier for my component to be integrated with others without causing them for starvation/contention for resource/threads.
EDIT 2
I have decided to completely embrace async model so that i won't be using thread pool threads to execute http requests, rather I can simply rely on "collaboration of OS Kernel and I/O completion port thread(s)" which will ensure that upon completion response will be sent in a callback (this way i can best use of cpu as well as resource). I am currently thinking of using (webclient.uploaddatataskasync) http://msdn.microsoft.com/en-us/library/system.net.webclient.uploaddatataskasync(v=vs.110).aspx, and update the code accordingly. (couple of references for details: HttpWebRequest and I/O completion ports, How does .NET make use of IO Threads or IO Completion Ports? )
EDIT 3
Basically i have used "async network I/O .net APIs as mentioned above" which essentially removed usage of my parallel library. For details, please see the below answer (i have added it for convenience, just in case if anyone is interested!).
psuedo code to give an idea how I am invoking web requests using webclient
//psudeo code to represents there can be varibale number of requests
//these can be ~500 to ~1000
foreach(var request in requests)
{
//psudeo code which basically executes webrequest in threadpool thread
//MY QUESTION: Is it OK to create as many worker threads as number rrequests
//and simply let them wait on a semaphore, on should i limit the concurrency?
MyThreadPoolConcurrentLibrary.ExedcuteAction(() =>
{
var sem = new Semaphore(initialCount: 50, maximumCount: 50.Value);
try
{
//using semaphore as the HTTP Server which i am taking to recommend
//to send '50' parallel requests in '30' TCP Connections
sem.WaitOne();
//using my custom webclient, so that i can configure 'tcp' connections
//(servicepoint connection limit) and ssl validation etc.
using (MyCustomWebClient client = new MyCustomWebClient())
{
//http://msdn.microsoft.com/en-us/library/tdbbwh0a(v=vs.110).aspx
//basically the worker thread simply waits here
client.UploadData(address: "urladdress", data: bytesdata);
}
}
finally
{
sem.Release(1);
}
});
}
MyThreadPoolConcurrentLibrary.WaitAll(/*...*/);
Basically should I do something to limit the number of threads I consume, or let the thread pool take care of it (i.e. in case if my app reaches thread pool's maximum thread limit, it any way queues the request - so I can simply rely on it)
*pseudo code which should show my custom webclient where I configure tcp connections, ssl validation etc.
class MyCustomWebClient : WebClient
{
protected override WebRequest GetWebRequest(Uri address)
{
HttpWebRequest request = (HttpWebRequest)base.GetWebRequest(address);
request.KeepAlive = true;
request.Timeout = 300;
request.ServicePoint.ConnectionLimit = TCPConnectionsLimit;
request.ServerCertificateValidationCallback = this.ServerCertificateValidationCallback;
return request;
}
private bool ServerCertificateValidationCallback(object sender, System.Security.Cryptography.X509Certificates.X509Certificate certificate, System.Security.Cryptography.X509Certificates.X509Chain chain, System.Net.Security.SslPolicyErrors sslPolicyErrors)
{
throw new NotImplementedException();
}
}
Best Regards.