如何修改一个for循环为Parallel.For? C#

How to modify a for cycle to Parallel.For? C#

我创建了一个非常简单的应用程序来计算 素数,然后将它们写下来。我想让它 运行 在所有核心上,如果用户选择计算例如 1 000 000...

如何将我已经在运行的 for cycle 转换为所有内核上的 运行? 我发现有一个 Parallel.For 但我真的不知道如何从我现有的 for 循环转换成它...

    {
        bool isPrime = true;
        int fPrime = Convert.ToInt32(txt_input.Text);
        Application.DoEvents();

        for (int i = 2; i <= fPrime; i++)
        {
            for (int j = 2; j <= fPrime; j++)
            {

                if (i != j && i % j == 0)
                {
                    isPrime = false;
                    break;
                }

            }

            if (isPrime)
            {
                txt_result.Text = txt_result.Text + "..." + i;
            }
            isPrime = true;
        }

        txt_result.Text = txt_result.Text + Environment.NewLine + "Done";
    }

更好的算法通常胜过更差(但并行化)的算法:

private static IEnumerable<int> Primes(int upTo) {
  if (upTo <= 1)
    yield break;

  yield return 2; // Special case: the only even prime

  List<int> primes = new List<int>() { };

  for (int number = 3; number <= upTo; number += 2) {
    int max = (int)(Math.Sqrt(number) + 0.5);
    bool isPrime = true;

    foreach (var div in primes)
      if (div > max)
        break;
      else if (number % div == 0) {
        isPrime = false;

        break;
      }

    if (isPrime) {
      primes.Add(number);

      yield return number;
    }
  }
}

...

txt_result.Text = string.Join(", ", Primes(1000000));

你会得到

2, 3, 5, 7, 11, 13, 17, 19, 23, ... 999959, 999961, 999979, 999983

几分之一秒

您将无法使用并行 foreach 更新 UI,您可以编写一个方法来 return 所有素数

        private static List<int> PrimeNumbers(int input)
        {
            var bag = new ConcurrentBag<int>();
            Parallel.ForEach(Enumerable.Range(2, input), x =>
            {
                var isPrime = true;
                Parallel.ForEach(Enumerable.Range(2, input), (y, state) =>
                {
                    if ((x != y) && (x % y) == 0)
                    {
                        isPrime = false;
                        state.Break();
                    }
                });
                if (isPrime)
                    bag.Add(x);
            });

            return bag.AsEnumerable().OrderBy(x => x).ToList();
        }

并行化外循环应该就足够了。您可能不会 运行 在处理器数量多于外部循环的机器中执行该程序!

Parallel.For(fromInclusive: 2, toExclusive: fPrime + 1, i =>
{
    for (int j = 2; j <= fPrime; j++)
    {

        if (i != j && i % j == 0)
        {
            isPrime = false;
            break;
        }

    }

    if (isPrime)
    {
        if (txt_result.InvokeRequired)
        {
            txt_result.Invoke((MethodInvoker)delegate { txt_result.Text = txt_result.Text + "..." + i; });
        }
        else
        {
            txt_result.Text = txt_result.Text + "..." + i;
        }
    }
    isPrime = true;
});
txt_result.Text = txt_result.Text + Environment.NewLine + "Done";