多次调用时,生成的随机字符串不是随机的

时间:2016-03-24 18:08:16

标签: c# asp.net

我正在尝试创建一个随机生成的单词串,除非我连续多次调用它,否则它会正常工作。这是在WebForms页面上,单词列表来自文件。

我怀疑我不理解C#中的某些东西,或者在这种情况下ASP.NET可能有效,有人可以解释为什么会发生这种情况以及如何解决问题吗?

这是方法

public string GeneratePhrase()
{
    // get dictionary file
    var data = File.ReadAllLines(HttpContext.Current.Server.MapPath("~/libs/words.txt"));

    Random rand = new Random();
    int r1 = rand.Next(data.Count());
    int r2 = rand.Next(data.Count());
    int r3 = rand.Next(data.Count());

    string p1 = data.ElementAt(r1).ToLower();
    string p2 = data.ElementAt(r2).ToLower();
    string p3 = data.ElementAt(r3).ToLower();

    string ret = string.Format("{0}{1}{2}", p1, p2, p3);
    return ret;
}

如果我在PostBack期间拨打一次,那就很好,并且总是创建一个随机的单词组合。但是,如果我在 PostBack 期间多次使用它,它只会在每次调用时重复相同的随机字符串。

string s1 = this.GeneratePhrase();
string s2 = this.GeneratePhrase();
string s3 = this.GeneratePhrase();
Response.Write(s1);
Response.Write(s2);
Response.Write(s3);

输出

tirefriendhotdog
tirefriendhotdog
tirefriendhotdog

为什么会发生这种情况有什么原因?

2 个答案:

答案 0 :(得分:6)

Random rand = new Random();使用当前时间作为种子值,因此快速连续多次调用它将为您提供相同的随机序列。你可以:

  • 创建一个用于所有请求的Random个对象
  • 使用不同的伪随机数(例如Guid.NewGuid().GetHashCode()
  • )播种
  • 使用与时间无关的其他随机数生成器。

答案 1 :(得分:4)

MSDNRandom

的无参数构造函数有这个说法
  

Random()构造函数使用系统时钟来提供种子值。这是实例化随机数生成器的最常用方法。

当您在短时间内创建几个Random的新实例时,它们最终可能会生成相同的种子,因此生成相同的序列。

要获得正确的(伪)随机性,最好在应用程序中每个线程只有一个Random个实例。