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

本文关键字:方法 返回 调用 循环 我的 为什么 | 更新日期: 2023-09-27 17:50:39

可能重复:
随机数生成器只生成一个随机数

我下面的代码正在做这件事,我不知道为什么:

如果我的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);
        }

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

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

您每次都要创建一个新的Random对象,由于它使用时间作为默认种子,因此您可以获得相同的种子,从而获得相同的数字。

将其作为类的字段,并且只创建一次。

这就是为什么当你走过它时,它会起作用。额外的时间允许种子改变并返回不同的结果。

这是因为您的方法使用

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

在循环中使用线程睡眠

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]);
        }