【问题标题】:.NET 4 ... Parallel.ForEach() question.NET 4 ... Parallel.ForEach() 问题
【发布时间】:2011-01-05 02:11:26
【问题描述】:

我了解新的 TPL(任务并行库)已经实现了 Parallel.ForEach(),因此它可以与“表达的并行性”一起使用。意思是,它不保证您的委托将在多个线程中运行,而是检查主机平台是否有多个内核,如果为真,那么它才会在内核之间分配工作(基本上每个内核 1 个线程) .

如果主机系统没有多个内核(越来越难找到这样的计算机),那么它将像“常规” foreach 循环一样按顺序运行您的代码。很酷的东西,坦率地说。

通常我会执行以下操作,将长时间运行的操作放在 ThreadPool 的后台线程上:

ThreadPool.QueueUserWorkItem(new WaitCallback(targetMethod), new Object2PassIn());

在主机只有一个内核的情况下,TPL 的 Parallel.ForEach() 是否会自动将调用置于后台线程上?或者,我是否应该从后台手动调用任何 TPL 调用,以便如果我从单核计算机执行,至少该逻辑将脱离 GUI 的调度线程?

我担心的是,如果我让 TPL 负责所有这一切,我想确保它是否确定它是一个单核盒,它仍然将 Parallel.ForEach() 循环内部的代码编组到后台线程,例如我会这样做,以免阻止我的 GUI。

感谢您的任何想法或建议...

【问题讨论】:

  • 快速跟进一下:TPL Rocks!无法克服使用 TPL 调用与“标准”票价相比,只需进行一些小的调整,我就能以多快的速度制作各种应用程序。我正在观察各种项目的处理时间减少了 80% 以上。 MS 真的把它从这个公园里淘汰了 - 干得好。

标签: c# .net parallel-processing


【解决方案1】:

您的假设不正确。
Parallel.For 始终是阻塞调用。

即使计算机有多个核心,它仍然会等待所有线程完成后再返回。

如果您不想冻结 UI,则始终需要显式调用 ThreadPool。

【讨论】:

  • 可以一直粘贴到Task中,使用continuation等待它完成,然后通知UI。
【解决方案2】:

根据我对 Parallel.ForEach 和 Parallel.For 循环的经验,我注意到顺序可能是无序的,在实施之前您可能需要考虑这一点。

比如一个基本的for循环会产生:

产品 1 产品 2 产品 3 产品4

并行循环可以产生,但并非总是如此:

产品 3 产品一 产品 2 产品4

请记住这一点,小伙子们。

【讨论】:

    【解决方案3】:

    我认为,如果您对实例/线程数有确切要求,则需要自己做。我的印象是 Parallel.ForEach 类型的调用是为了声明性地让核心参与进来。我不确定,但我有一个偷偷摸摸的怀疑,对于阻塞 i/o 的东西(例如),这将是一个糟糕的选择。

    【讨论】:

    • 从我目前阅读的文档来看,它最初是为“处理器绑定”问题集设计的。但是,这并不排除将其用于 IO。事实上,让我认真看待 TPL 是因为我有一个应用程序可以执行大约 7,800 个 Web 查询……我有一个运行 24GB RAM 的双四核处理器盒(3.0 GHz Xeons)在 Windows 7 Ultimate 64 位版本上……完成这些需要大约 25 到 28 分钟。下载 HTML 有一些额外的处理,但你明白我的意思。我将其更改为 TPL 调用,耗时
    【解决方案4】:

    好问题。我会假设即使只有一个内核,它仍然会产生一个线程。

    我必须在单核机器上运行测试。由于我没有,我将使用虚拟机并将 it 环境 CPU 设置为 1,然后查看 Parallel ForEach 将产生多少线程。

    您可能想阅读以下内容:

    Does Parallel limit the Number of Active Threads

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2012-03-25
      • 1970-01-01
      • 1970-01-01
      • 2011-11-21
      • 2011-06-12
      • 1970-01-01
      相关资源
      最近更新 更多