代码之家  ›  专栏  ›  技术社区  ›  explorer

线程能做什么,而基于任务的异步模式(TAP)和任务并行性(TPL)与任务(或任务<T>)不能做什么?

  •  1
  • explorer  · 技术社区  · 3 年前

    在阅读C#中的多线程时(都来自MSDocs和类似的书籍 Concurrency in C# Stephen Cleary),我反复遇到一些建议,这些建议基本上可以归结为:线程是较旧的、低级的并发抽象,被 Task Task<T> 类。

    现在我明白了,任务级别更高,功能更丰富、功能更强大,几乎可以做线程以前使用的任何事情,比如异步和并行。

    我的问题是:线程能做些什么吗 任务 任务<T> 等等,这样我就可以花时间学习多线程了,以防遇到这些用例?

    0 回复  |  直到 3 年前
        1
  •  1
  •   Theodor Zoulias    3 年前

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

    1. 当这些任务并行运行时,您将无法同步这些任务的操作。由于一无所知 lock s SemaphoreSlim s Mutex 锿, Barrier s Countdown 等等,您的并行和非同步任务将破坏应用程序的非线程安全状态。
    2. 通过使用 Interlocked
    3. 您将无法阻止编译器 reordering the instructions of your program ,导致您的任务遇到无效状态,因为您对内存障碍一无所知 volatile 关键字和 Volatile
    4. 您将无法启动 Task 其在STA线程上运行。
    5. 您将无法启动 任务 在前台线程上运行。
    6. 您将无法启动 任务 运行在具有 ThreadPriority 除了 Normal .
    7. 您将无法使用有效的对象池,在该池中,每个线程都可以使用自己的专用对象( ThreadLocal<T> ).

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

        2
  •  1
  •   Daniel James Bryars    3 年前

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

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