长时间运行的进程中,手动执行线程比使用线程池更好吗?

22

我前几天读到,对于长时间运行的任务,最好手动创建线程,而不是使用.NET的线程池或Task Parallel。由于我正在学习C#线程,特别是针对长时间运行的IO任务,因此我希望有人能给我指点迷津。提前感谢你。


1
请查看此问题:https://dev59.com/nnVC5IYBdhLWcg3woStW - Pragnesh Patel
2个回答

21

确实如此。线程池针对小单位的工作进行了优化,如果你持有线程池线程则可能会干扰其他任务。

我的经验法则是,如果操作可能需要超过一秒钟的时间,则不应在线程池线程上运行。这可能相当长。

虽然这没有得到记录,但如果您使用TaskCreationOptions.LongRunning启动Task,则会启动一个新线程来运行该任务。

对于大多数IO任务,您应该使用框架方法的异步版本。这些方法利用内核函数,意味着您不会阻塞任何线程。

像往常一样,我建议先阅读 Joe Albahari的免费电子书 ,然后再阅读Joe Duffy的《Windows并发编程》。后者长达1000页,但充满了有用的细节。


我会使用的标准是该线程是否预计有相当长时间的“等待”以等待某些事件发生,或执行其他线程可能正在等待的某些特定操作。 - supercat
Although this is undocumented, if you start a Task with TaskCreationOptions.LongRunning then a new Thread will be started to run the Task. Microsoft Docs added this in the mean time apparently https://learn.microsoft.com/en-us/dotnet/api/system.threading.tasks.taskcreationoptions?view=netframework-4.8
[...] It also provides a hint to the task scheduler that an additional thread might be required for the task [...]
- TorbenJ

10

你是对的,线程池线程是轻量级且廉价的,因为可以重新调度线程池中的线程来服务新的请求,所以一旦线程操作完成,线程池可以将同一线程重新调度到其他操作上,而且你可以通过设置最小线程数(ThreadPool.SetMinThreads())进行控制,这样它们就会一直保持活动状态,直到有新的请求到来。因此,这是处理多个轻量级操作的好方法,例如你需要每隔几秒钟创建一个新的线程。

非常好的 MSDN Magazine 的文章: Dedicated thread or a Threadpool thread?

一旦达到最小线程数,线程池会限制在 500 毫秒内创建线程的数量为一个。这是一个智能机制,避免了在该时间段内释放多个线程池线程时创建新线程的昂贵成本。

自 .NET 4.0 - 任务并行库(Task Parallel Library)是一个很好的高级抽象和手动线程管理和同步的替代方案,这样您的代码将更加容错。因此,只需使用TaskTaskCreationOptions.LongRunning创建一个任务,我相信这将是从可维护性的角度来看最好的应用程序架构投资。

有用的阅读材料:


非常感谢你们提供的指导。 - user1193665

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接