C# 创建并发程序的不同方法的差异

C# 创建并发程序的不同方法的差异,c#,.net-4.0,C#,.net 4.0,以下两者之间的区别是什么: 开始新的线程 使用第三方物流 使用BackgroundWorker 所有这些都创建了并发性,但它们之间的底层区别是什么?这三个都是线程吗 感谢他们都在内部使用线程,不同之处在于每个API的抽象级别以及线程的使用方式。让我们重新排列一下您的列表,看看从最低到最高抽象级别的三种技术: 手动启动新线程: 这实际上在操作系统中创建了一个新线程。您的代码将在该线程上执行 使用后台工作人员: 在内部,它使用一种叫做.net的东西。线程池基本上是一个可用线程池。您的代码被分配到一个

以下两者之间的区别是什么:

  • 开始新的线程
  • 使用第三方物流
  • 使用BackgroundWorker
  • 所有这些都创建了并发性,但它们之间的底层区别是什么?这三个都是线程吗


    感谢他们都在内部使用线程,不同之处在于每个API的抽象级别以及线程的使用方式。让我们重新排列一下您的列表,看看从最低到最高抽象级别的三种技术:

  • 手动启动新线程

    这实际上在操作系统中创建了一个新线程。您的代码将在该线程上执行

  • 使用后台工作人员

    在内部,它使用一种叫做.net的东西。线程池基本上是一个可用线程池。您的代码被分配到一个可用线程上,并在该线程上运行

    池管理可用线程的数量,并根据需要在特定范围内内部创建和销毁线程。这很有用,因为池可以有一些算法来优化线程创建。线程创建是一个非常昂贵的过程,因此如果合适的话,线程池会使线程保持活动状态,并在将来的请求中重用它们。通过指定最小/最大线程数和一些类似的小调整,您可以对池进行一些有限的控制

    还有其他直接使用线程池的方法,例如

  • 使用任务并行库

    这是一个更高的抽象概念。您创建“任务”并告诉TPL执行它们。TPL隐藏了所有关于到底有多少线程以及将使用哪些优先级等的问题。TPL能够重用线程,并根据特定的机器性能和可用的CPU资源对其进行管理

    例如,给定100个任务,在四核上TPL可能产生4个线程,但在8核上TPL可能产生8个线程,并在每个任务完成时将任务分配到可用线程上

  • 所以来回答你们的问题。所有3种技术都使用线程,但随着您提高每个级别,您对这些线程的控制和感知量会减少

    在大多数情况下,我建议您使用TPL。除非您需要对线程数量及其创建/销毁进行特定的非常精确的控制,否则TPL将为您很好地处理这一切

  • 启动一个新线程是三个线程中最昂贵的,但您得到的可能性最大。比如设置公寓模型和优先级

  • 任务并行库将在线程池上运行任务(除非任务标记为需要自己的线程),并添加异常处理和等待完成功能

  • BackgroundWorker仅用于运行从WinForms或WPF生成的任务。它还使用线程池

  • 额外:线程池。用于运行短任务,无需创建单独线程的开销


  • 创建一个线程只是。。。生成一个线程,以与主进程线程并发运行

    在TPL中,如果您创建一个任务,它将使用一个线程池来找到一个空闲线程来运行该任务。当您创建大量任务时,这可能会更有效,因为TPL能够在任意数量的空闲线程之间平衡负载(可能线程的数量是基于您拥有的内核的数量来平衡的,但我不确定这一点)

    最后,BackgroundWorker在一个单独的线程上运行您的工作。它实际上只是一个很好的抽象,它将您从线程的混乱部分中移除,因为它是为您管理的。如果我没弄错的话,它还提供了一种发回状态更新的方法。(不确定这是否使用Windows线程池,但我不会感到惊讶)

    最后,你必须选择适合你的课程,但是,TPL任务的目的是让您能够有效地调度可以并行运行的任务,而创建线程或使用后台工作线程对于长时间运行的操作或希望后台线程永远等待某个信号的场景可能更好(实际上,如果您只是在等待某个事件发出信号,我建议您使用RegisteredWait。)