我有一个线程,每次用户扫描条形码时都会关闭。
大多数情况下,它是一个相当短的运行线程。但有时它可能需要很长时间(等待调用GUI线程)。
我已经读过,为此使用ThreadPool可能是个好主意,而不是仅为每次扫描创建自己的线程。
但是我也读过,如果ThreadPool用完线程,那么它会等到其他一些线程退出(对我正在做的事情不行)。
那么,我有多大可能会耗尽线程? ThreadPool的好处真的值得吗? (当我扫描它时,扫描似乎不需要太长时间来“运行”线程逻辑。)
答案 0 :(得分:4)
这取决于“很长一段时间”的含义以及这种情况的常见程度。
MSDN主题“The Managed Thread Pool”为不使用线程池线程提供了很好的指导:
有几种情况适合创建和管理自己的线程而不是使用线程池线程:
- 您需要一个前台线程。
- 您需要一个具有特定优先级的线程。
- 您的任务导致线程长时间阻塞。该 线程池的最大数量 线程,所以大量被阻止 线程池线程可能会阻止 从开始的任务。
- 您需要将线程放入单线程单元中。所有 ThreadPool线程在 多线程公寓。
- 您需要拥有与该主题相关联的稳定标识,或者 将线程专用于任务。
答案 1 :(得分:1)
由于用户永远不会一次扫描多个条形码,因此线程池的内存成本可能不值得 - 我只需要在后台等待一个线程。
答案 2 :(得分:1)
线程池的要点是分摊创建线程的成本,这对于启动和拆除来说并不便宜。如果您有一个短期运行的任务,创建/销毁线程的成本可能是整个运行时的重要部分。线程池中的最大线程数取决于.NET Framework的版本,通常为每个处理器几十到几百个。根据可用的工作量来缩放线程数。
你是否会用完线程并且必须等待一个线程可用?这取决于您的工作量。您可以通过ThreadPool.GetMaxThreads()获得可用的最大线程数。有可能(基于您的问题的描述)这个数字足够高。
http://msdn.microsoft.com/en-us/library/system.threading.threadpool.getmaxthreads.aspx
另一种选择是管理您自己的扫描线程池并为其分配工作,而不是为每次扫描创建新线程。就个人而言,我会首先尝试线程池,只有在证明有必要时才管理自己的线程。更好的是,我会研究.NET中的异步编程技术。这些方法将在线程池上运行,但是比手动线程管理提供了更好的编程体验。
答案 3 :(得分:0)
如果大多数情况下它是短线程运行线程,你可以使用线程池或从池中抽取线程的BackgroundWorker。
答案 4 :(得分:0)
我在您的案例中可以看到的一个优点是,线程池类对可能处于活动状态的线程数量设置了上限。这取决于您的应用程序的上下文是否会耗尽系统资源。耗尽现代桌面系统非常难以实现。
如果软件在超市使用,那么您不太可能同时分析超过5个条形码。如果它在后端服务器中运行整排超市收费。然后可能有30-100个并发请求处于活动状态。
有了这种理论,即使在嵌入式硬件上,你也很可能会耗尽线程。如果您一次有十几个活动请求,并且您的代码正常工作,则可以保持原样。
线程池虽然只是一个抽象,你可以在中间排队,将请求排队到一个线程池,在这个场景中,对于上面的行直到例子,我觉得很舒服排队100-针对具有10个线程的线程池的1000个请求。
答案 5 :(得分:0)
在.net(以及一般的Windows)中,问题应该总是颠倒过来:“在这种情况下创建一个值得的新线程吗?”
创建一个新线程是昂贵的,并且一遍又一遍地做它几乎肯定是不值得的。线程池很便宜,当你需要一个新线程时,你应该首先找到它。
如果您决定启动一个新线程,很快就会开始担心如果线程已经运行则重新使用该线程。然后你会开始担心有时线程正在运行但似乎花了太长时间,所以你应该创建一个新线程。然后你决定让一个线程在完成工作后不立即退出,但等待一段时间以防新工作进来。然后...... bam!您已经创建了自己的线程池。此时您应该备份并使用系统提供的那个。
那些提到线程池可能“用完线程”的人是善意的,但他们对你有害。线程池中线程数的限制非常大。如果你遇到它,你还有其他问题。
(当然,因为.net 2.0,你可以设置最大线程数,所以如果你绝对需要,你可以调整一下。)
其他人已将您引导至MSDN:“The Managed Thread Pool”。我会重复那个方向,因为这篇文章很好,但在我看来并不是很难卖出线程池。 :)