System.Random默认构造函数使用的系统时钟分辨率是多少?

4
我有几个进程,其中使用 System.Random 的默认构造函数生成随机数。 我在 MSDN 上阅读了相关信息,但它并没有说明具体的系统时钟分辨率,例如 System.Random 是否以毫秒或秒为单位获取系统时钟种子?在多个进程中使用默认构造函数获取随机值是否安全?
谢谢。

1
看一下Jon Skeet的《C#深入》配套资料中的这一部分:随机数 - Dave New
4个回答

3
种子在10毫秒到16毫秒的范围内。但最重要的是要记住,如果可以生成不同的“随机”值,应始终使用相同的Random实例。如果您总是在紧密循环中创建新实例,则会多次获得相同的值。
因此,如果您始终使用相同的实例,则使用默认构造函数是“安全”的。如果不是因为您需要它们在不同的线程中,请使用Jon Skeet的这个帮助类(来自这里):
public static class RandomHelper
{
    private static int seedCounter = new Random().Next();

    [ThreadStatic]
    private static Random rng;

    public static Random Instance
    {
        get
        {
            if (rng == null)
            {
                int seed = Interlocked.Increment(ref seedCounter);
                rng = new Random(seed);
            }
            return rng;
        }
    }
}

系统中的 system.random() 实例在每个进程中都是唯一的,这样足够好吗? - KaiserJohaan
@KaiserJohaan 不太确定你的意思。这段代码为每个线程创建一个实例(感谢字段上的[ThreadStatic]),这是必需的,因为System.Random不是线程安全的。 - CodesInChaos
澄清一下,我有几个进程,在每个进程中我都有一个System.Random对象来生成值。我会得到唯一的值吗? - KaiserJohaan
你能澄清一下“process”是指什么样的进程吗?如果它们彼此独立,它们会生成不同(至少是随机的)值。 - Tim Schmelter
@KaiserJohaan 独特并不等同于随机。如果您在同一10-16毫秒间隔内创建Random对象,则有可能它们将以相同的种子开始。除非您不打算让它们在接近同一时间开始创建随机数,否则应使用非默认构造函数对它们进行初始化。 - Servy

3

它使用Environment.TickCount,您可以在反编译器中查看它。 但重点是获得一个唯一的种子,因此您可以对此值进行算术运算,并使用ProcessID。例如:

Random(Environment.TickCount + System.Diagnostics.Process.GetCurrentProcess().Id);

etc.


2

如果您正在使用不同的进程,请考虑使用进程ID为每个进程创建单个Random实例。

private static readonly Random _theSingleRandom = 
                          new Random(Process.GetCurrentProcess().Id);

2
可以将它(或其他内容)与时间戳进行异或操作,这样它仍然是与时间相关的吗? - Rawling
听起来这是迄今为止最好的建议。因此,本质上:private static readonly Random _theSingleRandom = new Random(Process.GetCurrentProcess().Id ^ Environment.TickCount); - Matthew Watson

0

根据我的经验,它在1到16毫秒之间。 - CodesInChaos

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