为什么我的循环从我调用的方法返回相同的值?

时间:2013-01-04 20:30:34

标签: c# random

  

可能重复:
  Random number generator only generating one random number

我的代码是这样做的,我不知道为什么:

如果我的toEmailAddresses数组包含2个电子邮件地址,uniqueID[0]uniqueID[1]将返回Util.CreateRandomPassword(16)方法调用生成的相同值。

如果我单步执行代码,则uniqueID[0]uniqueID[1]将包含不同的值。但是,如果我像往常一样运行代码,出于某种原因,相同的值会分配给我的uniqueID数组:uniqueID[0]uniqueID[1]将包含相同的值。

我甚至放入string tempRandomPassword = null然后将其分配给CreateRandomPassword方法返回的值,但这也不起作用。

我做错了什么?

//toEmailAddresses.Count array will have two e-mail addresses in it.

string[] uniqueID = new string[2];

for (int i = 0; i < toEmailAddresses.Count(); i++)
{
   string tempRandomPassword = null;
   tempRandomPassword = Util.CreateRandomPassword(16);

   uniqueID[i] = tempRandomPassword;
}


        public static string CreateRandomPassword(int passwordLength)
        {
            //http://madskristensen.net/post/Generate-random-password-in-C.aspx

            string allowedChars = "abcdefghijkmnopqrstuvwxyzABCDEFGHJKLMNOPQRSTUVWXYZ0123456789";
            char[] chars = new char[passwordLength];
            Random rd = new Random();

            for (int i = 0; i < passwordLength; i++)
            {
                chars[i] = allowedChars[rd.Next(0, allowedChars.Length)];
            }

            return new string(chars);
        }

4 个答案:

答案 0 :(得分:1)

这是因为您的方法使用

 Random rd = new Random();

Random的本地实例将使用时钟自动初始化,但是当两个实例创建得太近(在时间上)时,它们将使用相同的种子并生成相同的随机序列。

只要您不从多个线程调用此方法,就可以使用静态字段作为简单修复:

    private static Random _rd = new Random();

    public static string CreateRandomPassword(int passwordLength)
    {
        string allowedChars = "abcdefghijkmnopqrstuvwxyzABCDEFGHJKLMNOPQRSTUVWXYZ0123456789";
        char[] chars = new char[passwordLength];
        // Random rd = new Random();

        ...
    }

答案 1 :(得分:1)

每次创建一个新的Random对象,并且由于它使用time作为默认种子,因此获得相同的种子,从而得到相同的数字。

将其设为班级的一个字段,只创建一次。

这就是为什么当你顺便介入它时它起作用的原因。额外的时间允许种子改变并返回不同的结果。

答案 2 :(得分:1)

您正在使用每个调用的默认种子创建Random的新实例。如果种子是相同的,它将产生相同的数字序列。存储实例并将其用于所有调用。

答案 3 :(得分:-1)

在循环中使用线程休眠

private void button3_Click(object sender, EventArgs e)
        {
            string[] uniqueID = new string[2];
            string[] toEmailAddresses = new string[2];
            toEmailAddresses[0] = "a@1.com";
            toEmailAddresses[1] = "b@1.com";

            for (int i = 0; i < toEmailAddresses.Count(); i++)
            {
                uniqueID[i] = CreateRandomPassword(16);
                System.Threading.Thread.Sleep(10);               
            }

            for (int i = 0; i < uniqueID.Count(); i++)
                MessageBox.Show(i.ToString() + " : " + uniqueID[i]);
        }