C# – 线程池与任务

正如有些人在.NET 4.0中看到的,他们已经添加了一个新的命名空间System.Threading.Tasks ,它基本上就是一个任务。 我只用了几天,从使用ThreadPool。

哪一个更有效率,更less资源消耗? (或者只是更好的整体?)

Tasks命名空间的目标是提供可插拔的体系结构,使多任务应用程序更易于编写,并且更灵活。

该实现使用TaskScheduler对象来控制任务的处理。 这有虚拟的方法,你可以重写创build自己的任务处理。 方法包括例如

 protected virtual void QueueTask(Task task) public virtual int MaximumConcurrencyLevel 

使用默认实现将会有一个小小的开销,因为.NET线程实现有一个包装,但是我不希望它太大。

有一个自定义的TaskScheduler的实现(草稿),在这里在一个线程上实现多个任务。

哪一个更高效,更less资源消耗?

不相干的话,会有很小的差别。

(或者只是更好的整体)

Task类将更容易使用,因为它提供了一个非常干净的界面来启动和join线程,并传输exception。 它还支持(有限)forms的负载平衡。

“从.NET Framework 4开始,TPL是编写multithreading和并行代码的首选方式。”

http://msdn.microsoft.com/en-us/library/dd460717.aspx

调度是并行任务的一个重要方面。

与线程不同,新任务不一定立即开始执行。 相反,他们被放置在工作队列中。 任务在关联的任务调度程序从队列中移除时运行,通常在核心可用时运行。 任务调度程序试图通过控制系统的并发度来优化整体吞吐量。 只要有足够的任务,并且这些任务足够不依赖于序列化,程序的性能就会随着可用内核的数量而变化。 这样,任务体现了潜在的并行性的概念

正如我在http://msdn.microsoft.com/en-us/library/ff963549.aspx上看到的;

另一个值得考虑的关于任务的好处是,当你使用ThreadPool的时候,你没有办法中止或等待正在运行的线程(除非你在线程的方法中手动执行),但是使用任务是可能的 。 如果我错了,请纠正我

线

裸机的东西,你可能不需要使用它,你可能可以使用LongRunning任务,并从其设施中受益。

任务

线程之上的抽象。 它使用线程池 (除非您将任务指定为LongRunning操作,否则将为您创build一个新线程)。

线程池

顾名思义:线程池。 .NET框架为您处理有限数量的线程。 为什么? 因为打开100个线程在一个只有8个内核的CPU上执行昂贵的CPU操作绝对不是一个好主意。 该框架将为您维护此池,重用线程(不在每个操作中创build/杀死它们),并以CPU不会刻录的方式并行执行它们中的一些。

好的,但什么时候使用每一个?

在简历中:总是使用任务。

任务是一个抽象的,所以使用起来更容易。 我build议你总是尝试使用任务,如果你面临一些问题,你需要自己处理一个线程(可能是1%的时间),然后使用线程。

但请注意:

  • I / O绑定 :对于I / O绑定操作(数据库调用,读/写文件,API调用等), 从不使用普通任务 ,如果需要则使用LongRunning任务或线程,而不是普通任务。 因为它会导致你有一个线程池,有几个线程忙,还有很多其他的任务正在等待轮到池。
  • CPU绑定 :对于CPU绑定的操作,只需使用正常的任务,并高兴。