什么时候在 C# 中使用线程池?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/145304/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-03 15:30:59  来源:igfitidea点击:

When to use thread pool in C#?

提问by

I have been trying to learn multi-threaded programming in C# and I am confused about when it is best to use a thread pool vs. create my own threads. One book recommends using a thread pool for small tasks only (whatever that means), but I can't seem to find any real guidelines. What are some considerations you use when making this programming decision?

我一直在尝试在 C# 中学习多线程编程,但我对何时最好使用线程池与创建自己的线程感到困惑。一本书建议仅将线程池用于小任务(无论这意味着什么),但我似乎找不到任何真正的指导方针。在做出此编程决定时,您会考虑哪些因素?

采纳答案by Robert Gould

If you have lots of logical tasks that require constant processing and you want that to be done in parallel use the pool+scheduler.

如果您有许多需要持续处理的逻辑任务,并且您希望并行完成,请使用池+调度程序。

If you need to make your IO related tasks concurrently such as downloading stuff from remote servers or disk access, but need to do this say once every few minutes, then make your own threads and kill them once you're finished.

如果您需要同时执行与 IO 相关的任务,例如从远程服务器下载内容或磁盘访问,但需要每隔几分钟执行一次,然后创建自己的线程并在完成后终止它们。

Edit: About some considerations, I use thread pools for database access, physics/simulation, AI(games), and for scripted tasks ran on virtual machines that process lots of user defined tasks.

编辑:关于一些注意事项,我将线程池用于数据库访问、物理/模拟、AI(游戏),以及在处理大量用户定义任务的虚拟机上运行的脚本任务。

Normally a pool consists of 2 threads per processor (so likely 4 nowadays), however you can set up the amount of threads you want, if you know how many you need.

通常,一个池由每个处理器 2 个线程组成(现在可能是 4 个),但是如果您知道需要多少线程,您可以设置所需的线程数量。

Edit: The reason to make your own threads is because of context changes, (thats when threads need to swap in and out of the process, along with their memory). Having useless context changes, say when you aren't using your threads, just leaving them sit around as one might say, can easily half the performance of your program (say you have 3 sleeping threads and 2 active threads). Thus if those downloading threads are just waiting they're eating up tons of CPU and cooling down the cache for your real application

编辑:创建自己的线程的原因是上下文更改,(即线程需要交换进出进程以及它们的内存时)。有无用的上下文更改,比如当你不使用你的线程时,就像人们说的那样让它们闲着,很容易使你的程序性能减半(假设你有 3 个休眠线程和 2 个活动线程)。因此,如果那些下载线程只是在等待,它们会消耗大量 CPU 并为您的实际应用程序冷却缓存

回答by lajos

Thread pools are great when you have more tasks to process than available threads.

当您要处理的任务多于可用线程时,线程池非常有用。

You can add all the tasks to a thread pool and specify the maximum number of threads that can run at a certain time.

您可以将所有任务添加到一个线程池中,并指定某个时间可以运行的最大线程数。

Check out thispage on MSDN: http://msdn.microsoft.com/en-us/library/3dasc8as(VS.80).aspx

在 MSDN 上查看页面:http: //msdn.microsoft.com/en-us/library/3dasc8as(VS.80).aspx

回答by JeffFoster

Always use a thread pool if you can, work at the highest level of abstraction possible. Thread pools hide creating and destroying threads for you, this is usually a good thing!

如果可以,请始终使用线程池,尽可能在最高抽象级别上工作。线程池为你隐藏了创建和销毁线程,这通常是一件好事!

回答by paxdiablo

I would suggest you use a thread pool in C# for the same reasons as any other language.

出于与任何其他语言相同的原因,我建议您在 C# 中使用线程池。

When you want to limit the number of threads running or don't want the overhead of creating and destroying them, use a thread pool.

当您想限制运行的线程数或不想增加创建和销毁线程的开销时,请使用线程池。

By small tasks, the book you read means tasks with a short lifetime. If it takes ten seconds to create a thread which only runs for one second, that's one place where you should be using pools (ignore my actual figures, it's the ratio that counts).

对于小任务,您阅读的书意味着生命周期短的任务。如果创建一个只运行一秒钟的线程需要 10 秒钟,那么这就是您应该使用池的地方(忽略我的实际数字,重要的是比率)。

Otherwise you spend the bulk of your time creating and destroying threads rather than simply doing the work they're intended to do.

否则,您将大部分时间花在创建和销毁线程上,而不是简单地完成它们打算做的工作。

回答by Franci Penov

Here's a nice summary of the thread pool in .Net: http://blogs.msdn.com/pedram/archive/2007/08/05/dedicated-thread-or-a-threadpool-thread.aspx

这是 .Net 中线程池的一个很好的总结:http: //blogs.msdn.com/pedram/archive/2007/08/05/dedicated-thread-or-a-threadpool-thread.aspx

The post also has some points on when you should not use the thread pool and start your own thread instead.

这篇文章也有一些关于什么时候不应该使用线程池而应该启动自己的线程的观点。

回答by Brannon

The thread pool is designed to reduce context switching among your threads. Consider a process that has several components running. Each of those components could be creating worker threads. The more threads in your process, the more time is wasted on context switching.

线程池旨在减少线程之间的上下文切换。考虑一个有多个组件在运行的进程。这些组件中的每一个都可以创建工作线程。进程中的线程越多,在上下文切换上浪费的时间就越多。

Now, if each of those components were queuing items to the thread pool, you would have a lot less context switching overhead.

现在,如果这些组件中的每一个都将项目排队到线程池中,那么上下文切换开销就会少很多。

The thread pool is designed to maximize the work being done across your CPUs (or CPU cores). That is why, by default, the thread pool spins up multiple threads per processor.

线程池旨在最大限度地利用 CPU(或 CPU 内核)完成的工作。这就是默认情况下线程池为每个处理器启动多个线程的原因。

There are some situations where you would not want to use the thread pool. If you are waiting on I/O, or waiting on an event, etc then you tie up that thread pool thread and it can't be used by anyone else. Same idea applies to long running tasks, though what constitutes a long running task is subjective.

在某些情况下,您不想使用线程池。如果您正在等待 I/O 或等待事件等,那么您将占用该线程池线程并且其他任何人都无法使用它。同样的想法适用于长时间运行的任务,尽管构成长时间运行的任务是主观的。

Pax Diablo makes a good point as well. Spinning up threads is not free. It takes time and they consume additional memory for their stack space. The thread pool will re-use threads to amortize this cost.

Pax Diablo 也提出了一个很好的观点。旋转线程不是免费的。这需要时间,并且它们会为堆栈空间消耗额外的内存。线程池会重复使用线程来分摊这个成本。

Note: you asked about using a thread pool thread to download data or perform disk I/O. You should not use a thread pool thread for this (for the reasons I outlined above). Instead use asynchronous I/O (aka the BeginXX and EndXX methods). For a FileStreamthat would be BeginReadand EndRead. For an HttpWebRequestthat would be BeginGetResponseand EndGetResponse. They are more complicated to use, but they are the proper way to perform multi-threaded I/O.

注意:您询问了使用线程池线程来下载数据或执行磁盘 I/O。您不应该为此使用线程池线程(出于我上面概述的原因)。而是使用异步 I/O(又名 BeginXX 和 EndXX 方法)。对于 aFileStream那将是BeginReadEndRead。对于HttpWebRequest那将是BeginGetResponseEndGetResponse。它们使用起来更复杂,但它们是执行多线程 I/O 的正确方法。

回答by antonio

Most of the time you can use the pool as you avoid the expensive process of creating the thread.

大多数情况下,您可以使用池,因为您可以避免创建线程的昂贵过程。

However in some scenarios you may want to create a thread. For example if you are not the only one using the thread pool and the thread you create is long-lived (to avoid consuming shared resources) or for example if you want to control the stacksize of the thread.

但是在某些情况下,您可能想要创建一个线程。例如,如果您不是唯一一个使用线程池的人,并且您创建的线程是长期存在的(以避免消耗共享资源),或者例如您想控制线程的堆栈大小。

回答by Thomas Bratt

One reason to use the thread pool for small tasks only is that there are a limited number of thread pool threads. If one is used for a long time then it stops that thread from being used by other code. If this happens many times then the thread pool can become used up.

仅将线程池用于小任务的一个原因是线程池线程的数量有限。如果一个被使用了很长时间,那么它会阻止该线程被其他代码使用。如果这种情况发生多次,则线程池可能会用完。

Using up the thread pool can have subtle effects - some .NET timers use thread pool threads and will not fire, for example.

用完线程池会产生微妙的影响 - 例如,某些 .NET 计时器使用线程池线程并且不会触发。

回答by Bill

If you have a background task that will live for a long time, like for the entire lifetime of your application, then creating your own thread is a reasonable thing. If you have short jobs that need to be done in a thread, then use thread pooling.

如果你有一个后台任务会持续很长时间,比如你的应用程序的整个生命周期,那么创建你自己的线程是一件合理的事情。如果您有需要在线程中完成的短期作业,请使用线程池。

In an application where you are creating many threads, the overhead of creating the threads becomes substantial. Using the thread pool creates the threads once and reuses them, thus avoiding the thread creation overhead.

在您创建许多线程的应用程序中,创建线程的开销变得很大。使用线程池创建线程一次并重用它们,从而避免线程创建开销。

In an application that I worked on, changing from creating threads to using the thread pool for the short lived threads really helpped the through put of the application.

在我处理的一个应用程序中,从创建线程更改为对短期线程使用线程池确实有助于应用程序的吞吐量。

回答by mancaus

Beware of the .NET thread pool for operations that may block for any significant, variable or unknown part of their processing, as it is prone to thread starvation. Consider using the .NET parallel extensions, which provide a good number of logical abstractions over threaded operations. They also include a new scheduler, which should be an improvement on ThreadPool. See here

当心 .NET 线程池的操作可能会阻塞其处理的任何重要、可变或未知部分,因为它容易出现线程饥饿。考虑使用 .NET 并行扩展,它提供了大量对线程操作的逻辑抽象。它们还包括一个新的调度程序,这应该是对 ThreadPool 的改进。看这里