当前位置:  开发笔记 > 编程语言 > 正文

何时在C#中使用线程池?

如何解决《何时在C#中使用线程池?》经验,为你挑选了6个好方法。

我一直在尝试用C#学习多线程编程,我很困惑什么时候最好使用线程池而不是创建我自己的线程.一本书建议仅为小任务使用线程池(无论这意味着什么),但我似乎无法找到任何真正的指导方针.在做出此编程决策时,您使用了哪些注意事项?



1> paxdiablo..:

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

如果要限制运行的线程数或不希望创建和销毁它们的开销,请使用线程池.

通过小任务,您阅读的书意味着任务的寿命很短.如果创建一个只运行一秒的线程需要十秒钟,那么你应该使用池的一个地方(忽略我的实际数字,这是计算的比率).

否则,您将花费大量时间来创建和销毁线程,而不是简单地完成他们打算做的工作.



2> Robert Gould..:

如果您有许多需要持续处理的逻辑任务,并且您希望并行完成,请使用pool + scheduler.

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

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

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

编辑:创建自己的线程的原因是由于上下文更改(当线程需要交换进出进程时,以及它们的内存).无用的上下文更改,比如当你没有使用你的线程时,只要让他们坐在那里就像人们所说的那样,可以很容易地使你的程序性能降低一半(比如你有3个睡眠线程和2个活动线程).因此,如果那些下载线程只是在等待,那么他们就会占用大量CPU并为您的实际应用程序冷却缓存


空闲线程会影响性能吗?这取决于他们如何等待.如果编写好并等待同步对象,那么它们应该不占用CPU资源.如果在循环中等待定期唤醒以检查结果,则会浪费CPU.一如既往,它归结为良好的编码.
如果线程正在等待同步对象(事件,信号量,互斥体等),则线程不会消耗CPU.
正如Brannon所说,一个常见的误解是创建多个线程确实会影响性能.实际上,未使用的线程消耗的资源非常少.上下文切换仅在需求非常高的服务器中开始出现问题(在这种情况下,请参阅I/O完成端口以获取替代方案).
好的,但你能解释一下为什么这就是你接近它的方法吗?例如,使用线程池从远程服务器下载或执行磁盘IO的缺点是什么?
空闲的托管线程为堆栈吃内存.默认情况下,每个线程1 MiB.所以让所有线程都工作更好.

3> Franci Penov..:

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

当你不应该使用线程池并开始自己的线程时,帖子也有一些要点.


@ stimpy77 - 那是错误的期望.因此,它既不是自给自足的,也不是所有问题的最终权威,也不是所有关于每个主题的深入信息都可以(并且应该)在每个涉及该主题的SO答案中重复.(并且我认为你甚至没有足够的声誉来单独关注Jon Skeet的每一个有一个出站链接的答案,更不用说来自所有具有出站链接的SO用户的所有答案:-))
-1表示链接.我相信这是一个很好的联系,但我希望自给自足.
"你在发布这个帖子两年后来到这个帖子,我在这里复制的任何内容现在都可能已经过时了." 可能是一个链接.在发布链接时发布简洁但完整的摘要,您永远不会知道链接是陈旧还是死亡.
也许我过于简洁,也许我应该澄清一下.我不反对链接.我反对只包含链接的答案.我不认为这是一个答案.现在,如果已发布答案的简短摘要以总结链接内容的应用方式,那么这是可以接受的.此外,我来到这里寻找同一问题的答案,这个答案让我感到恼火,因为这是我必须点击的另一个链接,以便对于具体问题的参考可能有什么想法.无论如何,Jon Skeet与此有何关系?我为什么要关心?
我不同意吝啬:不是由于不可行性而包含大量信息的帖子的想法,也不是因为这个问题而打电话给某人.我会说它更可能是因为链接变得无法操作而不是内容被弃用/消除了.因此,当场合允许时,更多内容是很好的.我们都是(大多数)志愿者,所以要感谢你得到的 - 谢谢Franci :)

4> jrupe..:

我强烈推荐阅读这本免费的电子书: Joseph Albahari在C#中的线程化

至少阅读"入门"部分.电子书提供了很好的介绍,并包含了大量高级线程信息.

知道是否使用线程池只是一个开始.接下来,您需要确定哪种方法最适合您的线程池:

任务并行库(.NET Framework 4.0)

ThreadPool.QueueUserWorkItem

异步代理

的BackgroundWorker

这本电子书解释了这些,并建议何时使用它们而不是创建自己的线程.



5> Brannon..:

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

现在,如果每个组件都将项目排队到线程池,那么上下文切换开销就会少得多.

线程池旨在最大限度地提高CPU(或CPU内核)的工作量.这就是为什么默认情况下,线程池会为每个处理器旋转多个线程.

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

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

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



6> mancaus..:

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


我们发现这很难!ASP.Net使用Threadpool出现,所以我们不能像我们想的那样使用它.
推荐阅读
黄晓敏3023
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有