【问题标题】:Change for loop to Parallel.For loop将 for 循环更改为 Parallel.For 循环
【发布时间】:2016-12-01 15:30:39
【问题描述】:

我可以改变我的循环

for (int i = 0; i < something; i++)

到:

Parallel.For(0, something, i =>

但是如何用这个循环来做到这一点呢?:

for (i = 3; i <= something / 2; i = i + 2)

感谢您的回答。

【问题讨论】:

    标签: c# .net for-loop parallel-processing parallel.for


    【解决方案1】:

    自从

    for (int i = 3; i <= something / 2; i = i + 2)
    {
        ...
    }
    

    可以改写成

    for (int k = 1; k < (something + 2) / 4; ++k)
    {
        int i = 1 + 2 * k;
        ...
    }
    

    你可以放

    Parallel.For(1, (something + 2) / 4, k =>
    {
        int i = 1 + 2 * k; 
        ... 
    });
    

    【讨论】:

      【解决方案2】:

      第三个参数是delegate。所以每次迭代你都可以指定你的索引变量应该在委托中做什么。

      编辑: 好的,找到了一个可行的解决方案: 正如 Dmitry Bychenko 已经建议的那样,您仍然应该从 0 开始,只需添加 startValue 作为偏移量

      int something = 16;
      
      int startValue = 3;
      int stepSize = 2;
      
      List<int> numbers = Enumerable.Range(0, 20).ToList();
      
      Parallel.For(0, something / 2, i => 
      {
          int ind = (stepSize * i) + startValue ; Console.WriteLine(numbers[ind]);
      });
      

      【讨论】:

      • 这不符合他的要求。您的代码并行运行值 5、6、7、8、9,而他希望它等同于跳过每隔一个项目(值:3、5、7)的循环。
      • 请注意,在 delegate 内更改 i 不会更改 Parallel.For 计数,它只是一个复制的值类型 - int
      • 你不是说:var numbers = Enumerable.Range(0, 20).Where(i =&gt; i % 2 == 0).ToList();Parallel.For(i =&gt; { Console.WriteLine(i); });
      • @ilivewithian 这并不能解决问题。 OP 考虑编写正确的 For 循环而不是摆弄数据。
      • @TamirVered 感谢您指出i 的工作原理。真的很有启发性
      【解决方案3】:

      Dmitry Bychenko 的答案明白了,但您也可以使用自定义步骤实现自己的 ParallelFor,这将使您的代码更具可读性:

      static void ParallelFor(int start, int last, Func<int, int> step, Action<int> action)
      {
          var enumerable = StepEnumerable<int>
              .Create(start, step)
              .TakeWhile(x => x < last);
      
          Parallel.ForEach(enumerable, action);
      }
      

      这是StepEnumerable的实现:

      public class StepEnumerator<T> : IEnumerator<T>
      {
          ...
      
          public StepEnumerable(T value, Func<T, T> manipulation)
          {
              mEnumerator = new StepEnumerator<T>(value, manipulation);
          }
      
          public static StepEnumerable<T> Create(T value, Func<T, T> manipulation)
          {
              return new StepEnumerable<T>(value, manipulation);
          }
      
          ...
      }
      
      public class StepEnumerator<T> : IEnumerator<T>
      {
          public bool MoveNext()
          {
              Current = mManipulation(Current);
              return true;
          }
      }
      

      然后,例如,如果您运行以下代码:

      ParallelFor(3, 16, x => x + 2, Console.WriteLine);
      

      您将获得以下输出(当然是在单独的行中):

      5、11、7、13、9、15

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2014-03-15
        • 2018-08-13
        • 2017-09-26
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多