65

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

哪一个更高效,资源消耗更少?(或者只是整体更好?)

4

7 回答 7

26

Tasks 命名空间的目标是提供一个可插拔的架构,使多任务应用程序更容易编写和更灵活。

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

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

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

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

于 2009-11-21T07:30:05.127 回答
20

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

无关紧要,差别会很小。

(或者只是整体更好)

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

于 2009-11-21T10:20:40.630 回答
15

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

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

于 2012-06-05T23:52:52.370 回答
11

线

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

任务

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

线程池

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

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

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

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

但请注意:

  • I/O Bound:对于 I/O 绑定操作(数据库调用、读/写文件、API 调用等),永远不要使用普通任务LongRunning,如果需要,使用任务或线程,但不使用普通任务。因为它会引导你进入一个线程池,其中有几个线程很忙,还有很多其他任务等待轮到它占用池。
  • CPU Bound:对于 CPU 绑定操作,只需使用普通任务即可。
于 2017-07-14T22:53:55.077 回答
6

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

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

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

于 2012-04-17T13:13:13.387 回答
5

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

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

任务的简单定义可以是:

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

于 2018-09-14T11:46:34.237 回答
3

关于任务要考虑的另一个好点是,当您使用 ThreadPool 时,您没有任何方法可以中止或等待正在运行的线程(除非您在线程方法中手动执行此操作),但是使用任务是可能的。如果我错了请纠正我

于 2010-02-03T05:38:38.720 回答