C#平行随机。用于获得可重复序列

C#平行随机。用于获得可重复序列,c#,multithreading,random,seed,C#,Multithreading,Random,Seed,我正在从事一个C#项目,该项目要求在并行.for循环中使用随机数。为此,我使用Jon Skeet的MiscUtil中的StaticRandom类 对于测试,我希望能够重现我的结果。因此,我尝试为底层系统播种。Random以在每次测试运行时获得相同的序列。然而,即使有了种子,我每次都会得到不同的结果。在常规for循环中,每次输出相同的序列。下面是重现我的问题的代码(您必须用机器的输出更新预期序列) 有没有一种方法可以在并行的for循环中获得一个可重复的序列 [TestMethod]

我正在从事一个C#项目,该项目要求在并行.for循环中使用随机数。为此,我使用Jon Skeet的MiscUtil中的StaticRandom类

对于测试,我希望能够重现我的结果。因此,我尝试为底层系统播种。Random以在每次测试运行时获得相同的序列。然而,即使有了种子,我每次都会得到不同的结果。在常规for循环中,每次输出相同的序列。下面是重现我的问题的代码(您必须用机器的输出更新预期序列)

有没有一种方法可以在并行的for循环中获得一个可重复的序列

    [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());
    }

如果您在应用程序启动时获取所有随机样本,并将它们存储起来供以后使用,会怎么样。那么,采样线程使用它们的顺序就无关紧要了。另外,可能在一个特定的线程中执行所有采样本身,而不是调用?啊,是的。我假设它们是完全不同的序列,但实际上只是顺序不同。我将尝试在实际并行之前生成随机数。谢谢