C#随机函数返回相同的值

4
我是一名有用的助手,可以为您翻译文本。

可能重复:
随机数生成器不能按照我的计划工作(C#)

我已经编写了一个简单的程序来生成随机数。

private int randomNumber()
{
    Random random = new Random();
    int randomNum = random.Next(0, 100);
    Response.Write(randomNum);
    return randomNum;
}

我在页面加载过程中两个不同的阶段都以相同的方式调用它:
// A/B Test
if (randomNumber() <= 50)
{
...

我发现两个数字总是相同的。有什么想法吗?

在您开始从多个线程使用单个Random实例之前,请阅读http://csharpindepth.com/Articles/Chapter12/Random.aspx。 - Jon Skeet
我调用函数很多次,但每次它们都会给出不同的输出。 - Md Kamruzzaman Sarker
4个回答

13

当你创建一个 Random 实例时,它会以当前时间作为种子。因此,如果你同时创建多个实例,它们将生成相同的随机数序列。你需要创建一个单独的 Random 实例,并使用它。


好的,可以选择每个线程一个单独的实例或者一个带锁的单独实例... - Jon Skeet
看起来 Random 只考虑了时间部分?我的意思是,如果一个每天运行在相同时间的作业(当然日期不同),作业中使用的随机数仍然会生成相同的值(某种程度上)。我不确定这些值是否完全相同,但我有一个按随机值排序的列表,而且这个列表总是以相同的方式排序。 - Hopeless

7

new Random() 会以当前时间作为种子初始化。如果您调用得足够快,那么种子将是相同的,Next() 调用的结果也将相同。


3
你可以通过在类中拥有单个Random实例并重复使用它来解决此问题。
public class TestPage : Page
{
    private Random Generator {get;set;}
    public Test()
    {
        this.Generator = new Random();
    }
    private int randomNumber()
    {
        return this.Generator.Next(0, 100);
    }
}

这将为每个请求创建一个Random类。如果您想要将其放在一组用户中,则可以将生成逻辑包装在Singleton中,并在所有用户之间共享同一实例。

2

Random

使用一个基于时间的默认种子值来初始化 Random 类的新实例。

来自 MSDN。

默认种子值是从系统时钟中派生的,并具有有限的分辨率。因此,通过调用默认构造函数在短时间内创建的不同 Random 对象将具有相同的默认种子值,因此将生成相同的随机数集。可以通过使用单个 Random 对象生成所有随机数来避免这个问题。也可以通过修改系统时钟返回的种子值,然后显式地将这个新种子值提供给 Random(Int32) 构造函数来解决这个问题。有关更多信息,请参阅 Random(Int32) 构造函数。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接