需要帮助决定何时限制.net应用程序消耗的线程池线程数是一个好主意'

本文关键字:线程 一个 好主意 何时限 决定 帮助 net 应用程序 | 更新日期: 2023-09-27 18:09:17

我有HTTP客户端,基本上调用多个web请求对HTTP服务器。我在线程池线程(同步调用)中执行每个HTTP请求,默认情况下使用30 TCP(使用httpwebrequest)。Servicepoint (http://msdn.microsoft.com/en-us/library/system.net.httpwebrequest.servicepoint.aspx)。根据我所管理的系统,可能有~500/1000个线程池线程等待i/O (http响应)

现在,我想知道我是否需要限制我使用的线程数量?(例如,http://msdn.microsoft.com/en-us/library/ee789351(v=vs.110).aspx System.Threading.Tasks -限制并发任务的数量)

编辑

是的,我认为我需要限制我使用的线程数量,因为即使这些线程处于等待状态,它们也会占用资源。这样我就可以控制我使用的资源/线程的数量,这使得我的组件更容易与其他组件集成,而不会导致它们对资源/线程的饥饿/争用。

编辑2

我已经决定完全拥抱异步模型,这样我就不会使用线程池线程来执行http请求,而我可以简单地依靠"操作系统内核和I/O完成端口线程的协作",这将确保在完成响应后将在回调中发送(这样我可以最好地利用cpu以及资源)。我目前正在考虑使用(webclient.uploaddatataskasync) http://msdn.microsoft.com/en-us/library/system.net.webclient.uploaddatataskasync(v=vs.110).aspx,并相应地更新代码。(几个参考细节:HttpWebRequest和I/O完成端口,.NET如何使用IO线程或IO完成端口?)

编辑3

基本上我已经使用了"如上所述的异步网络i/O .net api",这基本上删除了我的并行库的使用。有关详细信息,请参阅以下答案(我为了方便起见添加了它,以防有人感兴趣!)

psuedo代码给一个想法,我是如何调用web请求使用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(/*...*/);

基本上我应该做些什么来限制我消耗的线程数量,或者让线程池照顾它(即,如果我的应用程序达到线程池的最大线程限制,它以任何方式排队请求-所以我可以简单地依赖它)

*伪代码,应该显示我的自定义web客户端,我配置tcp连接,ssl验证等

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();
    }
}

问好。

需要帮助决定何时限制.net应用程序消耗的线程池线程数是一个好主意'

因为我正在执行网络I/O (http web请求),使用'同步' httpwebrequests并让线程池线程阻塞同步调用并不是一个好主意。所以,我已经使用了"异步网络i/o操作(web客户端的异步任务方法),正如上面提到的问题,根据意见的建议。它自动删除了我的组件中线程数的使用-有关详细信息,请参阅下面的psuvideo代码片段…

这里有一些有用的链接,帮助我适应一些c# 5.0异步概念(async/await):

Deep Dive Video (很好的解释async/await状态机) http://channel9.msdn.com/events/TechDays/Techdays-2014-the-Netherlands/Async-programming-deep-dive

http://blog.stephencleary.com/2013/11/there-is-no-thread.html

async/await错误处理: http://www.interact-sw.co.uk/iangblog/2010/11/01/csharp5-async-exceptions, http://msdn.microsoft.com/en-us/library/0yd65esw.aspx,如何更好地理解代码/语句从" async-处理多个异常"文章吗?

好看的书: http://www.amazon.com/Asynchronous-Programming-NET-Richard-Blewett/dp/1430259205

class Program
{        
    static SemaphoreSlim s_sem = new SemaphoreSlim(90, 90);
    static List<Task> s_tasks = new List<Task>();   
    public static void Main()
    {                     
        for (int request = 1; request <= 1000; request++)
        {                             
            var task = FetchData();
            s_tasks.Add(task);                
        }
        Task.WaitAll(s_tasks.ToArray());
    }        
    private static async Task<string> FetchData()
    {
        try
        {
            s_sem.Wait();
            using (var wc = new MyCustomWebClient())
            {
                string content = await wc.DownloadStringTaskAsync(
                    new Uri("http://www.interact-sw.co.uk/oops/")).ConfigureAwait(continueOnCapturedContext: false);
                return content;
            }
        }
        finally
        {
            s_sem.Release(1);
        }
    }
    private class MyCustomWebClient : WebClient
    {
        protected override WebRequest GetWebRequest(Uri address)
        {
            var req = (HttpWebRequest)base.GetWebRequest(address);
            req.ServicePoint.ConnectionLimit = 30;
            return req;
        }
    }
}

问候。

您总是可以简单地瞄准浏览器运行的相同限制。这样服务器管理员就不会太讨厌你了。

现在,RFC说你应该限制连接到2个域,但是根据http://www.stevesouders.com/blog/2008/03/20/roundup-on-parallel-connections/

许多浏览器高达6或8个并行连接(这是在2008年)。

Browser HTTP/1.1    HTTP/1.0
IE 6,7         2    4
IE 8           6    6
Firefox 2      2    8
Firefox 3      6    6
Safari 3,4     4    4
Chrome 1,2     6    ?
Chrome 3       4    4
Chrome 4+      6    ?
iPhone 2       4    ?
iPhone 3       6    ?
iPhone 4        4   ?
Opera 9.63,     4   4
Opera 10.51+    8   ?