问题描述
我需要在 C# (MaxDegreeOfParallelism = Environment.ProcessorCount
) 中并行调用相同的方法。该方法返回一个数字序列。如果此序列满足某些标准 - 我需要执行以下操作
我有以下代码 - 但是我在弄清楚我写的 GetValidSequenze
方法中要写什么时遇到了一些问题://WHAT TO DO HERE??
有什么想法吗?我做错了什么吗?
public class Example3
{
public delegate int Randomizer(int minValue,int maxValue);
private Randomizer rand;
public Example3(Randomizer randomizer)
{
rand = randomizer;
}
private IEnumerable<bool> Infinite()
{
while (true)
{
yield return true;
}
}
public int[][] GetValidSequenze(int minValue,int maxValue,int rows,int columns,int sn,ref int counter)
{
ParallelOptions op = new ParallelOptions();
op.MaxDegreeOfParallelism = Environment.ProcessorCount;
int[][] result;
Parallel.ForEach(Infinite(),parallelOptions: op //WHAT TO DO HERE?? =>
{
int[][] tempRes;
while (!(tempRes = GetSequenze(minValue,maxValue,rows,columns))
.All(o => o.Contains(sn)))
{
Interlocked.Increment(ref counter);
}
loopState.Stop();
result = tempRes;
});
return result;
}
public int[][] GetSequenze(int minValue,int columns)
{
int[][] lot = new int[rows][];
for (int i = 0; i < rows; i++)
{
int[] column = new int[columns];
for (int j = 0; j < columns; j++)
{
while (true)
{
int tempNo = rand(0,40);
if (!column.Contains(tempNo))
{
column[j] = tempNo;
break;
}
}
}
lot[i] = column;
}
return lot;
}
}
解决方法
您的代码无法编译。以下是编译的 GetValidSequenze
方法的版本:
public int[][] GetValidSequenze(int minValue,int maxValue,int rows,int columns,int sn,ref int counter)
{
int localCounter = counter;
ParallelOptions op = new ParallelOptions();
op.MaxDegreeOfParallelism = Environment.ProcessorCount;
int[][] result = default;
Parallel.ForEach(Infinite(),parallelOptions: op,(_,loopState) =>
{
int[][] tempRes;
while (!(tempRes = GetSequenze(minValue,maxValue,rows,columns))
.All(o => o.Contains(sn)))
{
Interlocked.Increment(ref localCounter);
}
loopState.Stop();
result = tempRes;
});
counter = localCounter;
return result;
}
无论您想做什么,都可以通过改进算法来更有效地完成,而不是通过并行化一个可能效率低下的算法。
,定义一个您计划在满足条件时设置的变量。
bool criteriaMet = false;
遇到时设置。
修改您的枚举器:
private IEnumerable<bool> Infinite()
{
while (!criteriaMet)
{
yield return true;
}
}
如果您发现 Infinite()
方法未检测到 criteriaMet
中的任何更改,则可能是由于编译器优化。如果是这种情况,您可能需要使用 volatile 关键字,或者(更好)使用 CancellationToken 而不是 bool
。