C# - ThreadPool vs Tasks

The*_*eAJ 61 c# task threadpool

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

哪一个更有效,资源消耗更少?(或者总体上更好?)

Jer*_*Gee 25

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

该实现使用TaskScheduler对象来控制任务的处理.这有一些虚拟方法,您可以覆盖这些方法来创建自己的任务处理.方法包括例如

protected virtual void QueueTask(Task task)
public virtual int MaximumConcurrencyLevel
Run Code Online (Sandbox Code Playgroud)

使用默认实现会有很小的开销,因为有一个围绕.NET线程实现的包装器,但我不认为它会很大.

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

  • 一切都非常正确,但我不认为Task类的主要目的或吸引力是自定义调度程序.这是一个非常专业的功能,在某些情况下是非常宝贵的,但大多数用户永远不会触摸它. (9认同)

Hen*_*man 19

哪一个更有效,资源消耗更少?

不相关,差别很小.

(或者总体上更好)

Task类将更易于使用,因为它提供了一个非常干净的界面来启动和连接线程,并传输异常.它还支持(有限)形式的负载平衡.

  • 任务是在.NET中使用Parallel框架的一种更简单的方法.线程直接从操作系统中获取并立即运行,消耗更多的CPU时间,并且通常不允许框架管理上下文切换和优化技术.这类似于一个孩子扔一个TANTRUM和尖叫我现在想要!与某人等待轮到他们. (4认同)

Iva*_*čin 14

"从.NET Framework 4开始,TPL是编写多线程和并行代码的首选方式."

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


fab*_*tto 6

线

裸机,您可能不需要使用它,您可以使用LongRunningTask并从其功能中受益。

任务

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

线程池

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

OK,但是什么时候使用每个?

在简历中:始终使用任务。

任务是抽象的,因此使用起来容易得多。我建议您始终尝试使用“任务”,如果遇到一些问题,需要自己处理线程(大约1%的时间),请使用线程。

但是请注意:

  • I / O绑定:对于I / O绑定操作(数据库调用,读/写文件,API调用等),请不要使用常规任务LongRunning请根据需要使用任务或线程,但不要使用常规任务。因为这将导致您进入一个线程池,该线程池中有几个线程正在忙碌,并且还有许多其他任务在等待轮换使用该线程池。
  • CPU绑定:对于CPU绑定操作,只需使用常规任务并感到高兴。

  • 即使是一个相关的话题 `async` 和 `await` 也没有在这里讨论。但是,无论如何他们不鼓励 I/O 操作的“线程池线程”(正常任务)。我建议您查看@StephenCleary 的 [this](/sf/answers/1043189171/) 答案,他更详细地介绍了它。在他的两个例子中,他没有使用`Task.Run()`(这会产生一个在另一个上下文中执行的线程池线程)。其他答案也很有帮助。 (2认同)

Mic*_*ein 5

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

与线程不同,新任务不一定立即开始执行.相反,它们被放置在工作队列中.任务在其关联的任务计划程序将其从队列中删除时运行,通常在核心变为可用时运行.任务调度程序尝试通过控制系统的并发度来优化整体吞吐量.只要有足够的任务且任务完全没有序列化依赖关系,程序的性能就会随着可用内核的数量而扩展.通过这种方式,任务体现了潜在并行性的概念

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


小智 5

ThreadPoolTask 的区别很简单。要了解任务,您应该了解线程池。

ThreadPool基本上是帮助管理和重用空闲线程。换句话说,线程池是后台线程的集合。

任务的简单定义可以是:

任务工作异步管理工作单元。简而言之,Task 不会创建新线程。相反,它有效地管理线程池的线程。Tasks 由 TaskScheduler 执行,TaskScheduler 将任务排队到线程上。