Random.Next 不是线程安全的并且 returns 0 在 .netcore 中

Is Random.Next not Thread-Safe and returns 0 in .netcore

有没有人可以告诉我一些代码?

Instead of instantiating individual Random objects, we recommend that you create a single Random instance to generate all the random numbers needed by your app. However, Random objects are not thread safe. If your app calls Random methods from multiple threads, you must use a synchronization object to ensure that only one thread can access the random number generator at a time. If you don't ensure that the Random object is accessed in a thread-safe way, calls to methods that return random numbers return 0.

MSDN

任何可以证明这一点的代码

'If you don't ensure that the Random object is accessed in a thread-safe way, calls to methods that return random numbers return 0'

谢谢

如果您运行以下控制台应用程序(RELEASE 版本),您应该会在输出中偶尔看到零序列。

并不是每个随机值都会发生这种情况,但是当它发生时,您会连续得到很多零:

static class Program
{
    static void Main()
    {
        var rng = new Random(12345);

        Parallel.Invoke(
            () => test(rng),
            () => test(rng),
            () => test(rng),
            () => test(rng),
            () => test(rng),
            () => test(rng),
            () => test(rng),
            () => test(rng));
    }

    static void test(Random rng)
    {
        int[] numbers = new int[10000];

        for (int i = 0; i < numbers.Length; ++i)
            numbers[i] = rng.Next();

        for (int i = 0; i < numbers.Length; ++i)
            Console.WriteLine(numbers[i]);
    }
}

请注意,对于 DEBUG 构建,它不会发生(或发生得更少);这是线程错误的本质。

对于 RELEASE 版本,它甚至不会在每个 运行 上发生,但有时确实会发生(在我的 PC 上)。

你可以像这样构建一个简单的线程安全随机class

public class ThreadSafeRandom: Random
{
    private object LockObject = new object();

    public ThreadSafeRandom()
    { }

    public ThreadSafeRandom(int Seed) : base(Seed)
    { }

    public override int Next()
    {
        lock(LockObject)
        {
            return base.Next();
        }
    }

    // and so on with other virtual methods...
}