【问题标题】:What can Threads do that Task-based Asynchronous Pattern (TAP) and Task Parallelism (TPL) with Task (or Task<T>) cannot do?线程可以做什么,而基于任务的异步模式(TAP)和任务并行(TPL)与任务(或任务<T>)不能做什么?
【发布时间】:2026-01-17 01:25:02
【问题描述】:

在阅读 C# 中的多线程(来自 MSDocs 和 Stephen Cleary 的 Concurrency in C# 之类的书籍)时,我反复遇到的建议基本上归结为:线程是较旧的、低级别的抽象被TaskTask&lt;T&gt; 类取代的并发。

现在我了解到任务级别更高、功能更丰富、功能更强大,并且几乎可以执行线程以前用于异步和并行性的任何事情。

我的问题是:有什么线程可以做的,新的 TaskTask&lt;T&gt; 等不能做,所以我花时间学习多线程以防万一遇到这些用例?

【问题讨论】:

  • Task/Task&lt;T&gt; 涉及在多种情况下在幕后创建Thread。前者只是为后者精心设计的包装器,这使得正确使用多线程变得更加简单。如果您想真正了解一切是如何工作的,请从 Threads 开始,看看它们使用起来有多痛苦,然后切换到了解 Tasks、何时以及如何使用它们(尤其是在 async/@ 987654336@).
  • 这非常正确,是的。您永远不应该在常见的 LOB 应用程序中需要线程。当你对线程的生命周期和其他方面有严格的要求时,你会回到线程。通常,您只能使用 asyncawait 构建完整的应用程序(正确完成,阅读 Stephen Cleary 的 * 帖子和他的博客以获取更多信息)
  • 如果我想更改 Thread.Priority 或处理器关联/IO 优先级(使用 pinvoke)或设置 AppartmentState,我会使用线程而不是任务或线程池线程。跨度>
  • Is there anything that threads can do 它们允许您可靠地启动一个新线程。那有用吗?不常见,不。

标签: c# multithreading asynchronous .net-core concurrency


【解决方案1】:

是的,您也需要了解线程。如果您对多线程一无所知,以下是您将无法做到的事情的非详尽列表:

  1. 当这些任务彼此并行运行时,您将无法同步这些任务的操作。由于对locks、SemaphoreSlims、Mutexes、Barriers、Countdowns 等一无所知,您的并行和非同步任务将破坏应用程序的非线程安全状态。
  2. 您将无法通过使用 Interlocked 类对您的任务使用的变量和字段进行原子突变。
  3. 您将无法阻止编译器使用reordering the instructions of your program,从而导致您的任务遇到无效状态,因为您对内存屏障、volatile 关键字和Volatile 类一无所知。李>
  4. 您将无法启动在 STA 线程上运行的 Task
  5. 您将无法启动在前台线程上运行的 Task
  6. 您将无法启动在具有ThreadPriority 而非Normal 的线程上运行的Task
  7. 您将无法利用高效的对象池,其中每个线程都可以使用自己的专用对象 (ThreadLocal&lt;T&gt;)。

关于学习多线程,这里有一个免费的在线资源:Joseph Albahari 的Threading in C#

【讨论】:

  • 谢谢。我接受这个答案就足够了,因为它实际上回答了所制定的问题——尽管这个列表上的东西都是相当低级的用例——我的预期场景(我在问题中没有提到)是关于业务线 (LOB) 应用程序 --- 可以由问题下方的 cmets 判断。再次感谢您的列表,尤其是指向 Albahari 作品的链接。
  • @explorer 是的,只要您不使用任务来引入并行性,并且您的应用程序中的所有内容都按顺序运行,那么在您的情况下,学习线程将是相当多的学术知识。 :-)
【解决方案2】:

由于您提到的所有原因,任务都很好,它们可以重用池中的线程。这避免了拥有大量线程的开销(每个线程都需要一个堆栈,以及内核中的一些控制结构,跟踪它们等等),也避免了任务切换的开销——内核在线程之间转换需要一些周期.如果您有很多线程竞争同一个 CPU,那么您将花费更多时间进行切换,而花费更少的时间来做实际工作。

根据您的问题中的一个问题,直接使用线程意味着您可以控制生命周期,我唯一能想到的另一件事是线程本地存储 (https://docs.microsoft.com/en-us/dotnet/standard/threading/thread-local-storage-thread-relative-static-fields-and-data-slots)。

【讨论】: