[英]Confused with the Parallel.ForEach loop in C#
我是 C# 的新手,基本上是在嘗試使用 C# 中的 BigInteger 類生成大整數,方法是為其提供一個隨機填充值的 byte[] 數組。 我有另一種方法CheckForPrime(BigIngeger b)檢查素數,如果該數是素數則簡單地返回 true。 因此,為了運行所有內容,我使用了一個 Parallel ForEach 循環,該循環無限循環,直到條件為假。 這是我的代碼:
private static IEnumerable<bool> IterateUntilFalse(bool condition)
{
while (condition) yield return true;
}
這是我對 Parallel.ForEach 循環的嘗試,該循環一直運行到條件為假:
public void PrintOutPrimes(int numPrimes)
{
byte[] makeBytes = new byte[512];
BigInteger makePrime;
RandomNumberGenerator r = RandomNumberGenerator.Create();
ConcurrentBag<BigInteger> bbag = new ConcurrentBag<BigInteger>();
int trackNum = 0;
bool condition = (trackNum <= numPrimes);
Parallel.ForEach(IterateUntilFalse(condition), (ignored, state) =>
{
if (trackNum > numPrimes) state.Stop();
r.GetNonZeroBytes(makeBytes);
makePrime = BigInteger.Abs(new BigInteger(makeBytes));
if (CheckForPrime(makePrime))
{
bbag.Add(makePrime);
if(bbag.TryPeek(out makePrime))
{
Console.WriteLine(makePrime);
}
Interlocked.Increment(ref trackNum);
}
});
}
我想使用 Parallel.ForEach 的性能生成大素數,然后在找到它們時將它們打印出來。 問題似乎是代碼“繞過”了循環中的 if 語句,並將非素數添加到並發包中。 有沒有辦法避免這種情況並保證只將素數添加到袋子中然后按順序打印?
bool condition
不是條件,它是對條件進行一次評估的結果。 基本上它總是true
,永遠不會改變。 因此,您的迭代器將永遠產生true
。
為了解決這個問題,您需要一個可以多次評估的真實條件,例如 Lambda 表達式。 但即使使用 lambda,由於局部變量中的競爭條件,這也不能很好地工作。
實際上,我根本不明白您為什么要使用Parallel.Foreach
。 如果您想要 500 個素數,請使用Parallel.For
,而不是Parallel.Foreach
。
與其生成大量隨機數並檢查它們的素數,不如選擇一個隨機數並增加它,直到找到一個素數。 這樣可以保證您為每個隨機數輸入獲得一個素數。
概念:
Parallel.For(0, numPrimes, (i, state)=>
{
byte[] makeBytes = new byte[512];
r.GetNonZeroBytes(makeBytes);
BigInteger makePrime = BigInteger.Abs(new BigInteger(makeBytes));
while (!IsPrime(makePrime))
makePrime += 1; // at some point, it will become prime
bbag.Add(makePrime);
});
您可能希望從一個奇數開始並以 2 為增量。
你肯定希望每個線程有一個 RNG,而不是訪問一個全局 RNG,除非你有一個線程安全的 RNG。
您還希望byte[]
成為狀態的一部分,這樣它就不會在每個循環中重新創建並與垃圾收集相混淆。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.