C#-线程池与任务

C#-线程池与任务,c#,threadpool,task,C#,Threadpool,Task,正如一些人在.NET4.0中看到的,他们添加了一个新的名称空间System.Threading.Tasks,这基本上就是任务的意思。从使用ThreadPool开始,我只使用了几天 哪一个更高效、资源消耗更少?(或者总体来说更好?任务名称空间的目标是提供一个可插拔的体系结构,使多任务应用程序更易于编写和更灵活 该实现使用TaskScheduler对象来控制任务的处理。它具有虚拟方法,您可以重写这些方法来创建自己的任务处理。方法包括例如 protected virtual void QueueTas

正如一些人在.NET4.0中看到的,他们添加了一个新的名称空间
System.Threading.Tasks
,这基本上就是任务的意思。从使用ThreadPool开始,我只使用了几天


哪一个更高效、资源消耗更少?(或者总体来说更好?

任务名称空间的目标是提供一个可插拔的体系结构,使多任务应用程序更易于编写和更灵活

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

protected virtual void QueueTask(Task task)
public virtual int MaximumConcurrencyLevel
使用默认实现会有很小的开销,因为.NETThreads实现周围有一个包装器,但我不认为它会很大

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

哪一个效率更高,效率更低 资源消耗

不相干的话,就没有什么区别了

(或者总体上更好)


Task类将更易于使用,因为它为启动和加入线程以及传输异常提供了一个非常干净的接口。它还支持一种(有限的)负载平衡形式。

< P>另一个关于任务的好观点是,当使用线程池时,您没有任何方式中止或等待运行的线程(除非在线程方法中手动完成),但是使用任务是可能的。如果我错了,请纠正我

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

正如我在msdn上看到的那样,“从.NET Framework 4开始,TPL是编写多线程和并行代码的首选方式。”

螺纹 裸金属的东西,您可能不需要使用它,您可能可以使用
长时间运行的
任务,并从其设施中获益

任务 线程之上的抽象。它使用线程池(除非您将任务指定为
长时间运行
操作,否则会在后台为您创建一个新线程)

线程池 顾名思义:一个线程池。是指.NET framework为您处理有限数量的线程。为什么?因为在只有8个内核的CPU上打开100个线程来执行昂贵的CPU操作肯定不是一个好主意。框架将为您维护这个池,重用线程(不是在每次操作中创建/杀死线程),并以不会烧坏CPU的方式并行执行其中一些线程

好的,但是什么时候使用每一个呢? 在简历中:始终使用任务

任务是一个抽象的概念,所以它更容易使用。我建议您始终尝试使用任务,如果您遇到一些问题,需要自己处理线程(可能有1%的时间),则使用线程

但请注意:
  • I/O绑定:对于I/O绑定的操作(数据库调用、读/写文件、API调用等)切勿使用普通任务,如果需要,请使用
    LongRunning
    任务或线程,但不要使用普通任务。因为它会导致您进入一个线程池,其中有几个线程处于忙碌状态,还有很多其他任务等待轮到它接管该线程池
  • CPU受限:对于CPU受限的操作,只需使用正常任务,并保持愉快
线程池和任务的区别非常简单。 要理解任务,您应该了解线程池


ThreadPool基本上有助于管理和重用免费线程。在里面 换句话说,线程池是后台线程的集合

任务的简单定义可以是:

任务工作异步管理工作单元。简单地说 任务不会创建新线程。相反,它有效地管理 线程池的线程。任务由TaskScheduler执行,TaskScheduler将任务排入线程队列


我认为tasks利用了ThreadPool,这是非常正确的,但我不认为Task类的主要目的或吸引力是定制调度器。这是一个非常特殊的功能,在某些情况下非常宝贵,但大多数用户不会接触它。默认TaskScheduler只使用核心.NET Framework线程池。如果您不能中止任务,可以尝试取消它,但根据我的经验,这并不总是有效的。。。例如,作为Thread.Abort(),其中一个始终有效:)实际上,您可以使用cancellationtoken来取消线程池和任务。参见clr via c#Tasks是在.NET中使用并行框架的一种更简单的方法。线程直接从操作系统中获取并立即运行,消耗更多的cpu时间,并且通常不允许框架管理上下文切换和优化技术。这就像是一个孩子发脾气,尖叫我现在就要!与等待轮到他们的人较量。@MickeyPerlstein。在我看来,您对使用线程的描述并不真正适用于线程池(类ThreadPool),这正是OP所要求的。我同意任务是利用多个CPU的更有效的方法,特别是对于高级场景,但对于简单的情况
ThreadPool.QueueUserWorkItem
似乎就足够了。评论?@ToolmakerSteve使用一个系统,好好学习。这项任务是微软推荐的。QueueUserWorkItem有太多的怪癖