有没有人有任何好的资源可以显示在C#中创建无限数量的线程而不使用ThreadPool?
我意识到有人可能质疑具有数百或数千个线程的系统的体系结构,所以让我解释一下CPU / OS将使这项工作无法实现的任务。
我需要测试大约2500个网址。其中一些非常慢:响应时间超过10秒。无论如何,网络延迟占每项操作的99.99%。
我想尽快测试所有2500个网址。
我连接了一个测试,用自己的线程测试每个测试。
问题是我正在使用ThreadPool,我认为默认限制为25,所以这没有用。我需要手动管理它们。我可以在这里吃午饭吗?
我意识到CPU / OS可能也会限制每个CPU的并发线程数,但我相信这个限制是高于25的。
关于体系结构,我意识到如果我要连接2千个HTTP线程,我可能会锁定整个盒子,但这是一个在isoloation中运行的管理任务,可以使用尽可能多的资源。
感谢您的见解。
答案 0 :(得分:11)
您无法创建无限数量的线程。如果你尝试,你会遇到很多问题。
但是,您可以在C#中增加ThreadPool中的默认线程数。只需使用ThreadPool.SetMaxThreads为线程池提供更多可用的线程。它可能比任何手动线程尝试都做得更好(没有在手动过程中付出太多努力)。
答案 1 :(得分:4)
您还应该知道Windows XP(可能还有Vista / Win7)对您可以拥有的半开TCP连接数有限制(10)。如果您正在等待站点响应不存在,则添加更多线程将无法解决此问题。
答案 2 :(得分:3)
好吧,( 编辑:哎呀 - 这只是紧凑的框架)ThreadPool
中最大最大线程数是256,所以如果你需要更多,你必须手动完成。
手动启动新线程非常简单:
Thread newThread = new Thread(new ThreadStart(myWorkerMethod));
newThread.Start();
那就是说,你应该重新考虑你的方法。如果你需要那么多线程,你可能做错了。
答案 3 :(得分:2)
您可能还想查看其他ThreadPool提供程序;来自MiscUtil的MiscUtil.Threading.CustomThreadPool(由Jon Skeet编写)提供了一个自定义线程池实现,允许您指定最大线程数,同时还确保只有一组任务/应用程序正在使用线程池。
更确切地说;虽然你可能想要启动50-1000个线程,但你可能不应该通过并重新编写轮子,直到工作分配到线程为止。
另外,如果您使用HttpWebRequest和HttpWebResponse进行网址检查;您可能还需要修改:ServicePointManager.DefaultConnectionLimit。默认情况下,可以输出的并发WebRequest数量有限制(2或10),这可能会妨碍拥有能够运行数百个线程的计算机的任何可能的好处。
答案 4 :(得分:2)
我不确定这个答案是否已经提出,但我不认为需要超过2/3的线程。
一个线程只执行所有请求并完成。 第二个线程等待回复,一旦回复到达,它就会将回复列入回复队列。 第三个线程出列并处理回复。
简单明了。
有一个但是我不确定你是否可以在.net中异步接收http回复 我想你可以,但我不确定。
要么我完全忽略了这一点,要么你们的想法太复杂了。
答案 5 :(得分:2)
非常感谢...我希望我能接受多个答案。
我做的是
a。)将MaxThreads属性设置为100。 b。)放置
<system.net>
<connectionManagement>
<add address="*" maxconnection="100" />
</connectionManagement>
</system.net>
code in config
c。)将XP的TCP / IP限制从10增加到100。
d。)将ServicePointManager.DefaultConnectionLimit修改为100。
这些解决方案相结合,大大提高了性能。
现在我看到Henri的评论很有道理。
我可能甚至不需要线程......我可以让同一个线程触发对WebClient.DownloadStringAsync的调用,它会模拟我拥有的线程但更简单。
问题是,我可能会遇到内部WebClient / .NET限制,然后我需要解决这个问题......
答案 6 :(得分:1)
虽然需要测试2500个URL表明您需要2500个线程,但您不太可能需要全部2500个线程.ThreadPool将快速回收那些到达快速响应的Web地址的线程。
所以你可能会看到几十个线程的高峰。除此之外,我怀疑更多的线程将大大提高性能。由于线程开销,您将达到收益递减点。
答案 7 :(得分:1)
我遇到了类似的挑战,而不是使用线程池,我为每个想要命中的URL创建了一个线程,将其添加到队列中,然后从队列中弹出每个线程并启动它。我一直跟踪正在运行的线程的数量,当每个线程完成后,我抓住了下一个等待的线程。在我的用户界面中,我可以调整最大运行连接数,还可以查看排队连接数。
您遇到的是活动连接数超过活动线程数,因为这些线程在等待响应时被阻止。线程池重用线程并节省创建和启动线程的开销,这有助于您的处理是CPU密集型的;除非你有很多核心,否则25是合理的限制。但是当你在等待网络连接时,线程开销是微不足道的。
您可以通过设置maxconnection值来设置app.config中的最大限制(默认为2):http://msdn.microsoft.com/en-us/library/aa903351%28VS.71%29.aspx。
您可以创建大量线程,但只会为您启动的线程“收费”。你受到系统资源的限制,但我已经能够在没有严重性能影响的情况下逃脱数百人。
答案 8 :(得分:1)
您可能需要阅读The C10K problem,这是关于构建处理超过一万个连接的软件;它列出的大多数方法在Windows中都有类似物。 codeguru上有一个introduction to asynchronous sockets in C#。基本上在异步IO中,不是切换线程上下文和测试一个套接字的每个线程,而是使用事件驱动的方法,该方法挂钩到OS套接字实现以报告可用的套接字。您还可能需要调整注册表中的一些Windows TCP settings,例如最大连接数。
答案 9 :(得分:0)
您可以运行应用程序的多个实例,并在任务管理器上赋予它更高的优先级