线程可以做什么是基于任务的异步模式 (TAP) 和任务并行 (TPL) with Task(或 Task<T>)不能做的?
What can Threads do that Task-based Asynchronous Pattern (TAP) and Task Parallelism (TPL) with Task (or Task<T>) cannot do?
在阅读 C# 中的多线程时(包括 MSDocs 和 Stephen Cleary 的 Concurrency in C# 等书籍),我反复遇到的建议基本上可以归结为:线程较旧,低 -级别,由 Task
和 Task<T>
类.
取代的并发抽象
现在我明白任务是更高级别的,功能更丰富和更强大,并且几乎可以做线程以前用于异步和并行的任何事情。
我的问题是:有什么线程可以做的,较新的 Task
和 Task<T>
等不能做的,所以我花时间学习多线程以防万一我遇到那些用例?
由于您提到的所有原因,任务都很不错,而且它们可以重用池中的线程。这避免了拥有大量线程的开销(每个线程都需要一个堆栈,以及内核中的一些控制结构,跟踪它们等等)并且还避免了任务切换的开销 - 内核在线程之间转换需要一些周期.如果您有很多线程竞争同一个 CPU,那么您将花更多的时间切换,而花更少的时间进行实际工作。
根据对您的问题的评论之一,直接使用线程意味着您可以控制生命周期,我唯一能想到的就是线程本地存储(https://docs.microsoft.com/en-us/dotnet/standard/threading/thread-local-storage-thread-relative-static-fields-and-data-slots)。
是的,你也需要了解线程。如果您对多线程一无所知,以下是您将无法执行的事情的非详尽列表:
- 当这些任务 运行 彼此并行时,您将无法同步这些任务的操作。由于对
lock
s、SemaphoreSlim
s、Mutex
es、Barrier
s、Countdown
s 等一无所知,您的并行和非同步任务将破坏应用程序的非线程安全状态。
- 您将无法使用
Interlocked
class. 对您的任务使用的变量和字段进行原子突变
- 您将无法阻止编译器使用 reordering the instructions of your program, resulting to your tasks encountering invalid state, because you'll know nothing about memory barriers, the
volatile
关键字和 Volatile
class.
- 您将无法启动在 STA 线程上运行的
Task
。
- 您将无法启动在前台线程上运行的
Task
。
- 您将无法启动在
ThreadPriority
而非 Normal
的线程上运行的 Task
。
- 您将无法利用高效的对象池,其中每个线程都可以使用自己的专用对象 (
ThreadLocal<T>
)。
对于学习多线程,这里有一个免费的在线资源:Threading in C# Joseph Albahari。
在阅读 C# 中的多线程时(包括 MSDocs 和 Stephen Cleary 的 Concurrency in C# 等书籍),我反复遇到的建议基本上可以归结为:线程较旧,低 -级别,由 Task
和 Task<T>
类.
现在我明白任务是更高级别的,功能更丰富和更强大,并且几乎可以做线程以前用于异步和并行的任何事情。
我的问题是:有什么线程可以做的,较新的 Task
和 Task<T>
等不能做的,所以我花时间学习多线程以防万一我遇到那些用例?
由于您提到的所有原因,任务都很不错,而且它们可以重用池中的线程。这避免了拥有大量线程的开销(每个线程都需要一个堆栈,以及内核中的一些控制结构,跟踪它们等等)并且还避免了任务切换的开销 - 内核在线程之间转换需要一些周期.如果您有很多线程竞争同一个 CPU,那么您将花更多的时间切换,而花更少的时间进行实际工作。
根据对您的问题的评论之一,直接使用线程意味着您可以控制生命周期,我唯一能想到的就是线程本地存储(https://docs.microsoft.com/en-us/dotnet/standard/threading/thread-local-storage-thread-relative-static-fields-and-data-slots)。
是的,你也需要了解线程。如果您对多线程一无所知,以下是您将无法执行的事情的非详尽列表:
- 当这些任务 运行 彼此并行时,您将无法同步这些任务的操作。由于对
lock
s、SemaphoreSlim
s、Mutex
es、Barrier
s、Countdown
s 等一无所知,您的并行和非同步任务将破坏应用程序的非线程安全状态。 - 您将无法使用
Interlocked
class. 对您的任务使用的变量和字段进行原子突变
- 您将无法阻止编译器使用 reordering the instructions of your program, resulting to your tasks encountering invalid state, because you'll know nothing about memory barriers, the
volatile
关键字和Volatile
class. - 您将无法启动在 STA 线程上运行的
Task
。 - 您将无法启动在前台线程上运行的
Task
。 - 您将无法启动在
ThreadPriority
而非Normal
的线程上运行的Task
。 - 您将无法利用高效的对象池,其中每个线程都可以使用自己的专用对象 (
ThreadLocal<T>
)。
对于学习多线程,这里有一个免费的在线资源:Threading in C# Joseph Albahari。