在这种情况下,ThreadPool 值得吗?

发布于 2024-10-06 09:16:36 字数 280 浏览 4 评论 0 原文

我有一个线程,每次用户扫描条形码时都会触发该线程。

大多数时候,它是一个相当短的运行线程。但有时可能需要很长时间(等待对 GUI 线程的调用)。

我读到,为此使用 ThreadPool 可能是一个好主意,而不仅仅是为每次扫描创建我自己的线程。

但我还读到,如果 ThreadPool 耗尽了线程,那么它只会等待,直到其他线程退出(对于我正在做的事情来说不合适)。

那么,我用完线程的可能性有多大?线程池的好处真的值得吗? (当我扫描时,扫描“运行”线程逻辑似乎并没有花费太长时间。)

I have a thread that I fire off every time the user scans a barcode.

Most of the time it is a fairly short running thread. But sometimes it can take a very long time (waiting on a invoke to the GUI thread).

I have read that it may be a good idea to use the ThreadPool for this rather than just creating my own thread for each scan.

But I have also read that if the ThreadPool runs out of threads then it will just wait until some other thread exits (not OK for what I am doing).

So, how likely is it that I am going to run out of threads? And is the benefit of the ThreadPool really worth it? (When I scan it does not seem to take too long for the scan to "run" the thread logic.)

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(6

深者入戏 2024-10-13 09:16:36

这取决于你所说的“很长一段时间”是什么意思以及这种情况有多常见。

MSDN 主题“托管线程池”提供了关于何时使用的良好指南使用线程池线程:

有几种情况适合创建和管理自己的线程而不是使用线程池线程:

  • 您需要一个前台线程。
  • 您需要一个线程具有特定的优先级。
  • 您的任务会导致线程长时间阻塞。这
    线程池有最大数量
    线程,所以大量阻塞
    线程池线程可能会阻止
    从一开始就完成任务。
  • 您需要将线程放入单线程单元中。全部
    ThreadPool 线程位于
    多线程公寓。
  • 您需要拥有与该线程关联的稳定身份,或者
    将线程专用于任务。

It depends on what you mean by "a very long time" and how common that scenario is.

The MSDN topic "The Managed Thread Pool" offers good guidelines for when not to use thread pool threads:

There are several scenarios in which it is appropriate to create and manage your own threads instead of using thread pool threads:

  • You require a foreground thread.
  • You require a thread to have a particular priority.
  • You have tasks that cause the thread to block for long periods of time. The
    thread pool has a maximum number of
    threads, so a large number of blocked
    thread pool threads might prevent
    tasks from starting.
  • You need to place threads into a single-threaded apartment. All
    ThreadPool threads are in the
    multithreaded apartment.
  • You need to have a stable identity associated with the thread, or to
    dedicate a thread to a task.
夜声 2024-10-13 09:16:36

由于用户永远不会一次扫描多个条形码,因此线程池的内存成本可能不值得 - 我会坚持使用一个在后台等待的线程。

Since the user will never scan more than one barcode at a time, the memory costs of the threadpool might not be worth it - I'd stick with a single thread just waiting in the background.

混吃等死 2024-10-13 09:16:36

线程池的目的是分摊创建线程的成本,而线程的启动和销毁并不便宜。如果您有一个短期运行的任务,那么创建/销毁线程的成本可能会占整个运行时间的很大一部分。线程池中的最大线程数取决于 .NET Framework 的版本,通常每个处理器数十到数百个。线程数量根据可用工作进行缩放。

您是否会耗尽线程并必须等待线程变得可用?这取决于你的工作量。您可以通过 ThreadPool.GetMaxThreads() 获取可用的最大线程数。这个数字很可能(根据问题的描述)足够高。

http://msdn.microsoft.com/en-us /library/system.threading.threadpool.getmaxthreads.aspx

另一种选择是管理自己的扫描线程池并为其分配工作,而不是为每次扫描创建新线程。就我个人而言,我会首先尝试线程池,并且仅在必要时管理您自己的线程。更好的是,我会研究 .NET 中的异步编程技术。这些方法将在线程池上运行,但为您提供比手动线程管理更好的编程体验。

The point of the thread pool is to amortize the cost of creating threads, which are not inexpensive to spin up and tear down. If you have a short-running task, the cost of creating/destroying the thread can be a significant portion of the overall run-time. The maximum number of threads in the thread pool depends on the version of the .NET Framework, typically dozens to hundreds per processor. The number of threads is scaled depending on available work.

Will you run out of threads and have to wait for a thread to become available? It depends on your workload. You can get the maximum number of threads available via ThreadPool.GetMaxThreads(). Chances are (based on the description of your problem) that this number is sufficiently high.

http://msdn.microsoft.com/en-us/library/system.threading.threadpool.getmaxthreads.aspx

Another option would be to manage your own pool of scan threads and assign them work rather than creating a new thread for every scan. Personally I would try the threadpool first and only manage your own threads if it proved necessary. Even better, I would look into async programming techniques in .NET. The methods will be run on the thread pool, but give you a much nicer programming experience than manual thread management.

天生の放荡 2024-10-13 09:16:36

如果大多数情况下运行时间较短的线程,您可以使用线程池或 BackgroundWorker 从池中提取线程。

If most of the time it is short running threads you could use the thread pool or a BackgroundWorker which draws threads from the pool.

若相惜即相离 2024-10-13 09:16:36

我在你的例子中看到的一个优点是线程池类对可能处于活动状态的线程数量设置了上限。是否会耗尽系统资源取决于您的应用程序的上下文。耗尽现代桌面系统实际上是非常困难的。

如果该软件在超市中使用,那么同时分析超过 5 个条形码的可能性极小。如果它在一整排超市收银机的后端服务器中运行。那么可能有 30-100 个并发请求处于活动状态。

通过这种理论构建,即使在嵌入式硬件上,您也不太可能耗尽线程。如果您一次有十几个左右的请求处于活动状态,并且您的代码可以正常工作,那么就可以保持原样。

不过,线程池只是一个抽象,您可以在中间有一个队列,将请求排队到线程池中,在上面的 row-of-till 示例的场景中,我会很舒服地对 100-1000 个请求进行排队具有 10 个线程的线程池。

An advantage I can see in your case is that threadpool class puts an upper limit on the amount of threads that may be active. It depends on the context of your application whether you will exhaust system resources. Exhausting a modern desktop system is VERY hard to do really.

If the software is used in a supermarket till it is highly unlikely that you will have more then 5 barcodes being analysed at the same time. If its run in a back-end server for a whole row of supermarket tills. Then perhaps 30-100 concurrent requests might be active.

With this sort of theory crafting it is highly unlikely that you will run out of threads, even on embedded hardware. If you have a dozen or so requests active at a time, and your code works, it's ok to just leave it as it is.

A thread pool is just an abstraction though, and you could have queue in the middle that queues request onto a thread-pool, in this scenario for the row-of-till example above, I'd feel comfortable queueing 100-1000 requests against a threadpool with 10 threads.

旧人九事 2024-10-13 09:16:36

在 .net 中(以及一般的 Windows 上),问题应该始终相反:“在这种情况下创建新线程值得吗?”

创建一个新线程的成本很高,而且一遍又一遍地这样做几乎肯定是不值得的。线程池很便宜,当您需要新线程时,确实应该首先使用线程池。

如果您决定启动一个新线程,很快您就会开始担心重新使用该线程(如果它已经在运行)。然后你会开始担心有时线程正在运行但似乎花费了太长的时间,因此你应该创建一个新线程。然后,您将决定让线程在完成工作后不立即退出,而是等待一段时间,以防新工作进入。然后...砰!您已经创建了自己的线程池。此时您应该备份并使用系统提供的备份。

那些提到线程池可能“线程用完”的人是出于好意,但他们却给你带来了伤害。线程池中线程数量的限制相当大。如果你遇到了它,你还会遇到其他问题。

(当然,从 .net 2.0 开始,您可以设置最大线程数,因此您可以在必要时调整该数量。)

其他人已将您引导至 MSDN:“托管线程池”。我会重复这个方向,因为这篇文章很好,但在我看来,线程池的推销力度还不够。 :)

In .net (and on windows in general), the question should always be reversed: "Is creating a new thread worth it in this scenario?"

Creating a new thread is expensive, and doing it over and over again is almost certainly not worth it. The thread pool is cheap, and really should be the first thing you turn to when you need a new thread.

If you decide to spin up a new thread, soon you will start worrying about re-using the thread if it's already running. Then you will start worrying that sometimes the thread is running but it seems to be taking too long, and so you should make a new one. Then you're going to decide to have a thread not exit immediately upon finishing work, but to wait a little while in case new work comes in. And then... bam! You've created your own thread pool. At which point you should just back up and use the system-provided one.

The folks who mentioned that the thread pool might "run out of threads" were well-intentioned, but they did you a disservice. The limit on the number of threads in the thread pool is quite large. If you run into it, you have other problems.

(And, of course, since .net 2.0, you can set the maximum number of threads, so you can tweak the number if you absolutely have to.)

Others have directed you to MSDN: "The Managed Thread Pool". I will repeat that direction, as the article is good, but in my mind does not sell the thread pool hard enough. :)

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文