qx4235
qx4235

Reputation: 31

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

Is there any one could show me some codes ?

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

any codes that can demonstrate this

'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'

Thanks

Upvotes: 2

Views: 372

Answers (2)

Dubbs777
Dubbs777

Reputation: 377

You can build a simple thread safe random class like this

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...
}

Upvotes: 1

Matthew Watson
Matthew Watson

Reputation: 109852

If you run the following console application (RELEASE build), you should see occasional sequences of zeros in the output.

It doesn't happen for every random value, but when it happens, you get quite a few zeroes in a row:

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

Note that it doesn't happen (or happens a lot less) for a DEBUG build; this is the nature of threading errors.

It doesn't even happen on every run for a RELEASE build, but it does happen sometimes (on my PC).

Upvotes: 2

Related Questions