【发布时间】:2010-12-18 23:33:45
【问题描述】:
正如一些人可能在 .NET 4.0 中看到的那样,他们添加了一个新的命名空间 System.Threading.Tasks,这基本上就是一个任务。从使用 ThreadPool 开始,我只使用了几天。
哪一个更高效,资源消耗更少? (或者只是整体更好?)
【问题讨论】:
-
我认为任务使用了线程池。
标签: c# threadpool task
正如一些人可能在 .NET 4.0 中看到的那样,他们添加了一个新的命名空间 System.Threading.Tasks,这基本上就是一个任务。从使用 ThreadPool 开始,我只使用了几天。
哪一个更高效,资源消耗更少? (或者只是整体更好?)
【问题讨论】:
标签: c# threadpool task
Tasks 命名空间的目标是提供一种可插拔的架构,使多任务应用程序更易于编写和更灵活。
该实现使用TaskScheduler 对象来控制任务的处理。这具有您可以覆盖以创建自己的任务处理的虚拟方法。方法包括例如
protected virtual void QueueTask(Task task)
public virtual int MaximumConcurrencyLevel
使用默认实现会有很小的开销,因为 .NET 线程实现有一个包装器,但我不认为它会很大。
有一个自定义 TaskScheduler 的(草稿)实现,它在单个线程 here 上实现多个任务。
【讨论】:
哪一种效率更高,效率更低 消耗资源?
无关紧要,差别很小。
(或者只是整体更好)
Task 类将更易于使用,因为它为启动和加入线程以及传输异常提供了一个非常干净的接口。它还支持(有限的)负载平衡形式。
【讨论】:
ThreadPool.QueueUserWorkItem 似乎完全足够了。评论?
“从 .NET Framework 4 开始,TPL 是编写多线程和并行代码的首选方式。”
【讨论】:
裸机的东西,你可能不需要使用它,你可能可以使用 LongRunning 任务并从它的设施中受益。
线程之上的抽象。它使用线程池(除非您将任务指定为LongRunning 操作,如果是这样,则会在后台为您创建一个新线程)。
顾名思义:线程池。 .NET 框架是否为您处理有限数量的线程。为什么?因为在只有 8 个内核的 CPU 上打开 100 个线程来执行昂贵的 CPU 操作绝对不是一个好主意。框架将为您维护这个池,重用线程(不是在每个操作中创建/杀死它们),并以您的 CPU 不会烧毁的方式并行执行其中的一些。
在简历中:始终使用任务。
Task 是一个抽象,所以它更容易使用。我建议您始终尝试使用任务,如果您遇到一些需要自己处理线程的问题(可能有 1% 的时间),那么请使用线程。
LongRunning 任务或如果你需要线程,但不是正常的任务。因为它会引导你进入一个线程池,其中有几个线程很忙,还有很多其他任务等待轮到它占用池。 【讨论】:
async 和 await 的鼓励。
async 和 await 的相关主题,这里也没有讨论。但是,无论如何,他们不支持 I/O 操作的“线程池线程”(正常任务)。我建议您查看@StephenCleary 的this 答案,他在其中更详细地介绍了它。在他的两个示例中,他都没有使用Task.Run()(这会产生在另一个上下文中执行的线程池线程)。其他答案也很有帮助。
LongRunning 任务进行I/O”有什么关系,ConfigureAwait 只会导致CPU 绑定在I/O 上执行/O-bound 线程,它仍然来自一个 Task 线程池线程..
与线程不同,新任务不一定会立即开始执行。相反,它们被放置在工作队列中。任务在其关联的任务调度程序将它们从队列中删除时运行,通常是在内核可用时。任务调度器试图通过控制系统的并发程度来优化整体吞吐量。只要有足够多的任务并且这些任务完全没有序列化依赖项,程序的性能就会随着可用内核的数量而扩展。这样,任务就体现了潜在并行的概念
正如我在 msdn 上看到的 http://msdn.microsoft.com/en-us/library/ff963549.aspx
【讨论】:
ThreadPool和Task的区别很简单。 要了解任务,您应该了解线程池。
ThreadPool 基本上有助于管理和重用空闲线程。在 换句话说,线程池是后台线程的集合。
任务的简单定义可以是:
Task工作异步管理工作单元。用简单的话 任务不会创建新线程。相反,它有效地管理 线程池的线程。Tasks 由 TaskScheduler 执行,TaskScheduler 将任务排队到线程中。
【讨论】:
另一个需要考虑的关于任务的好点是,当您使用 ThreadPool 时,您没有任何方法可以中止或等待正在运行的线程(除非您在线程方法中手动执行),但是 使用任务是可能的。如有错误请指正
【讨论】: