简体   繁体   English

C#手动线程

[英]C# Manual Threading

Does anyone have any good resources that show creating an unlimited number of threads in C# WITHOUT using a ThreadPool? 有没有人有任何好的资源显示在C#中创建无限数量的线程而不使用ThreadPool?

I realize one might question the architecture of a system with hundreds or thousands of threads, so let me explain the task in case the CPU/OS will make this effort moot. 我意识到有人可能质疑具有数百或数千个线程的系统的体系结构,所以让我解释一下CPU / OS将使这项工作没有实际意义的任务。

I have about 2500 URLs that I need to test. 我需要测试大约2500个网址。 Some of them are very slow: in excess of 10 seconds to respond. 其中一些非常慢:响应时间超过10秒。 In any event, network latency makes up about 99.99% of each operation. 无论如何,网络延迟占每项操作的99.99%。

I'd like to test all 2500 urls as fast as possible. 我想尽快测试所有2500个网址。

I wired up a test that tests each of them in their own thread. 我连接了一个测试,在他们自己的线程中测试每个测试。

The problem is I'm using the ThreadPool and I think the default limit is 25, so that's no good. 问题是我正在使用ThreadPool,我认为默认限制是25,所以这没有用。 I need to manage them manually. 我需要手动管理它们。 Am I way out to lunch here? 我出去吃午饭吗?

I realize the CPU/OS will probably also limit the number of concurrent threads per CPU, but I trust this limit is WAY higher than 25. 我意识到CPU / OS可能也会限制每个CPU的并发线程数,但我相信这个限制是高于25的。

Regarding architecture, I realize I may be locking up an entire box if I was to wire up 2 thousand HTTP threads, but this is an admin task that runs in isoloation and can take as many resources as are available. 关于体系结构,我意识到如果我要连接2千个HTTP线程,我可能会锁定整个盒子,但这是一个在isoloation中运行的管理任务,可以使用尽可能多的资源。

Thanks for your insights. 感谢您的见解。

You cannot create an unlimited number of threads. 您无法创建无限数量的线程。 You will run into many problems if you try. 如果你尝试,你会遇到很多问题。

However, you can increase the default number of threads in the ThreadPool in C#. 但是,您可以在C#中增加ThreadPool中的默认线程数。 Just use ThreadPool.SetMaxThreads to give the thread pool more threads with which to work. 只需使用ThreadPool.SetMaxThreads为线程池提供更多可用的线程。 It will likely do a better job than any manual threading attempts (without putting a LOT of effort into the manual process). 它可能比任何手动线程尝试都做得更好(没有在手动过程中投入大量精力)。

You should also be aware that Windows XP (and possibly Vista/Win7) have a limit on the number of half-open TCP connection you can have (10). 您还应该知道Windows XP(可能还有Vista / Win7)对您可以拥有的半开TCP连接数有限制(10)。 If you are waiting for sites to respond that don't exist, adding more threads won't get around this problem. 如果您正在等待站点响应不存在,则添加更多线程将无法解决此问题。

Well, the maximum maximum number of threads in ThreadPool is 256, so if you need more, you'll have to do it manually. 好吧, ThreadPool 最大的最大线程数是256,所以如果你需要更多,你必须手动完成。 ( Edit : Whoops -- that's compact framework only) 编辑 :哎呀 - 这只是紧凑的框架)

Starting a new thread manually is as easy as: 手动启动新线程非常简单:

Thread newThread = new Thread(new ThreadStart(myWorkerMethod));
newThread.Start();

That said, you should probably reconsider your approach. 那就是说,你应该重新考虑你的方法。 If you need that many threads, odds are you're doing it wrong. 如果你需要那么多线程,你可能做错了。

You may also want to look into a different ThreadPool provider; 您可能还想查看不同的ThreadPool提供程序; MiscUtil.Threading.CustomThreadPool from MiscUtil (authored by Jon Skeet) provides a Custom Thread Pool implementation that allows you to specify a maximum number of threads, while also ensuring that only one set of tasks/applications is using the Thread Pool. 来自MiscUtil的MiscUtil.Threading.CustomThreadPool (由Jon Skeet编写)提供了一个自定义线程池实现,允许您指定最大线程数,同时还确保只有一组任务/应用程序正在使用线程池。

More precisely; 更确切地说; while you may want to spin up 50-1000 threads, you probably shouldn't go through and rewrite the wheel as far as work distribution to threads goes. 虽然你可能想要启动50-1000个线程,但是就线程的工作分配来说,你可能不应该通过并重写轮子。

Also, if you are using HttpWebRequest and HttpWebResponse for url checking; 另外,如果您使用HttpWebRequest和HttpWebResponse进行网址检查; you'll probably also need to modify: ServicePointManager.DefaultConnectionLimit . 您可能还需要修改:ServicePointManager.DefaultConnectionLimit。 By default, there's a limit on the number of concurrent WebRequests that can be out (either 2 or 10), which rather hampers any possible benefit from having a machine capable of running several hundred threads. 默认情况下,可以输出的并发WebRequest数量(2或10)是有限制的,这相当于阻碍了拥有能够运行数百个线程的计算机的任何可能的好处。

Im not sure if this answer is already proposed but i dont see the need for more than 2/3 threads. 我不确定这个答案是否已经提出,但我不认为需要超过2/3的线程。

One thread just does all the request and finishes. 一个线程只执行所有请求并完成。 The second thread waits for the replies, once a reply arrives, it enqueues the replies in a reply queue. 第二个线程等待回复,一旦回复到达,它就会将回复列入回复队列。 The third thread dequeues and processes the replies. 第三个线程出列并处理回复。

Just plain and simple. 简单明了。

There is one BUT, im not sure if you can asynchronously receive http replies in .net I assume you can, but im not sure. 有一个但是我不确定你是否可以在.net中异步接收http回复我认为你可以,但我不确定。

Either i'm missing the point completely or you guys are thinking way too complicated. 要么我完全忽略了这一点,要么你们的想法太复杂了。

Thanks a lot guys...I wish I could accept multiple answers. 非常感谢...我希望我能接受多个答案。

What I did was 我做的是

a.) Set the MaxThreads property to 100. b.) Place the a。)将MaxThreads属性设置为100. b。)放置

<system.net>
    <connectionManagement>
      <add address="*" maxconnection="100" />
    </connectionManagement>
  </system.net>

code inside config 配置内部的代码

c.) Up the TCP/IP limit of XP to 100 from 10. c。)将XP的TCP / IP限制从10增加到100。

d.) Modify the ServicePointManager.DefaultConnectionLimit to 100. d。)将ServicePointManager.DefaultConnectionLimit修改为100。

These solutions combined greatly increased the performance. 这些解决方案的组合大大提高了性能

Now I see though that Henri's comment makes a good deal of sense. 现在我看到Henri的评论很有道理。

I may not even need threads...I could have the same thread fire a call to WebClient.DownloadStringAsync which would simulate the threads I have but be much simpler. 我可能甚至不需要线程...我可以让同一个线程触发对WebClient.DownloadStringAsync的调用,这将模拟我拥有的线程但更简单。

The problem is again, I may run into internal WebClient/.NET limitations that I would then need to work around... 问题是,我可能遇到内部WebClient / .NET限制,然后我需要解决...

Although the need to test 2500 URLs suggests that you need 2500 threads, it is highly unlikely you will need all 2500. The ThreadPool will rapidly recycle those threads that reach a web address that responds quickly. 虽然需要测试2500个URL表明您需要2500个线程,但您不太可能需要全部2500个线程.ThreadPool将快速回收那些到达快速响应的Web地址的线程。

So you may see peaks of a few dozen threads. 所以你可能会看到几十个线程的高峰。 Beyond that, I doubt that more threads will substantially increase performance. 除此之外,我怀疑更多的线程将大大提高性能。 You will reach a point of diminishing returns due to the thread overhead. 由于线程开销,您将达到收益递减点。

I had a similar challenge and instead of using the thread pool, I created a thread for each URL I wanted to hit, added it to a Queue, and then popped each thread off of the queue and started it. 我遇到了类似的挑战,而不是使用线程池,我为每个想要命中的URL创建了一个线程,将其添加到队列中,然后将每个线程弹出队列并启动它。 I kept track of the number of running threads, and as each one completed then I grabbed the next waiting thread. 我一直跟踪正在运行的线程的数量,当每个线程完成后,我抓住了下一个等待的线程。 In my user interface I could tweak the maximum running connections and also watch the number of queued connections. 在我的用户界面中,我可以调整最大运行连接,还可以查看排队连接的数量。

What you're up against is the number of active connections more than the number of active threads, as these threads are blocked while they're waiting for a response. 您遇到的是活动连接数超过活动线程数,因为这些线程在等待响应时被阻止。 The thread pool reuses threads and saves you the overhead of creating and starting threads, which helpswhen your processing is CPU-intensive; 线程池重用线程并节省创建和启动线程的开销,这有助于您的处理是CPU密集型的; 25 is a reasonable limit unless you have a lot of cores. 除非你有很多核心,否则25是合理的限制。 But when you're waiting on a network connection, the thread overhead is insignificant. 但是当你在等待网络连接时,线程开销是微不足道的。

You can set the maximum limit (defaults to two) in your app.config by setting the maxconnection value: http://msdn.microsoft.com/en-us/library/aa903351%28VS.71%29.aspx . 您可以通过设置maxconnection值来设置app.config中的最大限制(默认为2): http//msdn.microsoft.com/en-us/library/aa903351%28VS.71%29.aspx

You can create a large number of threads, but you only get "charged" for threads you start. 您可以创建大量线程,但只为您启动的线程“收费”。 You're limited by system resources, but I've been able to get away with hundreds without a serious performance hit. 你受到系统资源的限制,但是我已经能够在没有严重性能损失的情况下逃脱数百人。

You might want to read The C10K problem which is about building software to handle more than ten thousand connections; 您可能希望阅读C10K问题该问题涉及构建处理超过一万个连接的软件; most of the approaches it lists have analogues in Windows. 它列出的大多数方法在Windows中都有类似物。 There's an introduction to asynchronous sockets in C# on codeguru. 在codeguru上的C#中异步套接字介绍 Basically in asynchronous IO, rather than switching thread contexts and each thread testing one socket, an event driven approach is used which hooks into the OS socket implementation to report the sockets which are available. 基本上在异步IO中,不是切换线程上下文和测试一个套接字的每个线程,而是使用事件驱动的方法,该方法挂钩到OS套接字实现以报告可用的套接字。 You also might want to tweak some of the Windows TCP settings in the registry, such as the maximum number of connections. 您还可能需要调整注册表中的某些Windows TCP设置 ,例如最大连接数。

您可以运行应用程序的多个istances,并在任务管理器上赋予它更高的优先级

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM