C#平行随机。用于获得可重复序列
我正在从事一个C#项目,该项目要求在并行.for循环中使用随机数。为此,我使用Jon Skeet的MiscUtil中的StaticRandom类 对于测试,我希望能够重现我的结果。因此,我尝试为底层系统播种。Random以在每次测试运行时获得相同的序列。然而,即使有了种子,我每次都会得到不同的结果。在常规for循环中,每次输出相同的序列。下面是重现我的问题的代码(您必须用机器的输出更新预期序列) 有没有一种方法可以在并行的for循环中获得一个可重复的序列C#平行随机。用于获得可重复序列,c#,multithreading,random,seed,C#,Multithreading,Random,Seed,我正在从事一个C#项目,该项目要求在并行.for循环中使用随机数。为此,我使用Jon Skeet的MiscUtil中的StaticRandom类 对于测试,我希望能够重现我的结果。因此,我尝试为底层系统播种。Random以在每次测试运行时获得相同的序列。然而,即使有了种子,我每次都会得到不同的结果。在常规for循环中,每次输出相同的序列。下面是重现我的问题的代码(您必须用机器的输出更新预期序列) 有没有一种方法可以在并行的for循环中获得一个可重复的序列 [TestMethod]
[TestMethod]
public void MultiThreadedSeededRandom()
{
var actual = new ConcurrentBag<int>();
Parallel.For(0, 10, i =>
{
actual.Add(StaticRandom.Next(1000));
});
WriteActualToOutput(actual);
var expected = new int[] { 743, 51, 847, 682, 368, 959, 245, 849, 192, 440, };
Assert.IsTrue(AreEqual(expected, actual.ToArray()));
}
public static bool AreEqual<T>(T[] expected, T[] actual)
{
if (expected.Length != actual.Length)
return false;
for (int i = 0; i < expected.Length; i++)
{
if (!expected[i].Equals(actual[i]))
return false;
}
return true;
}
private static void WriteActualToOutput(ConcurrentBag<int> acual)
{
var result = string.Empty;
result += "new int[] {";
foreach (var value in acual)
{
result += value.ToString() + ",";
}
result += "};";
Trace.WriteLine(result);
}
public static class StaticRandom
{
private static Random random = new Random(1231241);
private static object myLock = new object();
public static int Next(int max)
{
object obj;
Monitor.Enter(obj = StaticRandom.myLock);
int result;
try
{
result = StaticRandom.random.Next(max);
}
finally
{
Monitor.Exit(obj);
}
return result;
}
}
[TestMethod]
public void多线程种子随机数()
{
var实际值=新的ConcurrentBag();
对于(0,10,i=>
{
实际添加(StaticRandom.Next(1000));
});
WriteActualToutput(实际输出);
var expected=newint[]{743,51847,682,368,959,245,849,192,440,};
Assert.IsTrue(AreEqual(预期的,实际的.ToArray());
}
公共静态布尔值相等(T[]预期值,T[]实际值)
{
如果(预期的.Length!=实际的.Length)
返回false;
for(int i=0;i
当您使用并行时。对于
,通过设计,您将得到顺序不同的结果,因为每个迭代将以不确定的方式并行运行。如果需要相同的“随机”数序列,则需要以可靠的顺序调用random.Next()
。这在多个线程中不起作用
<> >而不是尝试使用<代码>并行。对于填充随机数,应考虑预先生成“随机数”序列,然后使用<代码>并行。对于在这些事实之后基于这些数字进行处理。这样,您将始终以正确的顺序生成数字,这将保留顺序。另一个注意事项是,如果您从未使用过StringBuilder,您可以在输出方法中使用StringBuilder的效率:
private static void WriteToArrayString(ICollection items)
{
var result = new StringBuilder("new []{");
var index = 0;
foreach(var value in items)
{
if (index == (items.Count - 1))
{
result.Append(string.Concat(value));
index++;
continue;
}
result.Append(string.Concat(value, ','));
index++;
}
result.Append("};");
Trace.WriteLine(result.ToString());
}
如果您在应用程序启动时获取所有随机样本,并将它们存储起来供以后使用,会怎么样。那么,采样线程使用它们的顺序就无关紧要了。另外,可能在一个特定的线程中执行所有采样本身,而不是调用?啊,是的。我假设它们是完全不同的序列,但实际上只是顺序不同。我将尝试在实际并行之前生成随机数。谢谢