I'm writing an application for testing an algorithm with random generated inputs. This involves several instances of Random class spread around the code. I need all these instances to generate same inputs in different runs to debug the algorithm when I find an unexpected result. This is the behavior of the apps created with Delphi, unless you manually call Randomize.
I know I can:
Provide constant seeds for all created instances.
Pass a unique instance, which is created with a constant seed, to all methods that need a random generator.
The reason I prefer not to use any of the above methods is that most of the functions that generate random data are kind of black box functions that are collected here and there on the Internet. Some of them even use several random generators for unknown reasons. I prefer not to mess with these functions unless I really have to.
So, are there any other ways to control all these instances together?
Here's a quick example of a class with two static members, one a "fixed RNG", while the other just a normal "RNG", that you can use from anywhere in your code:
int x = MyRandom.RNG.Next(1, 7);
int y = MyRandom.FixedRNG.Next(1, 7);
Code:
public class MyRandom
{
private static Random _fixedRandom = new Random(1234);
private static Random _random = new Random();
public static Random FixedRNG
{
get
{
return _fixedRandom;
}
}
public static Random RNG
{
get
{
return _random;
}
}
}
An alternative might be to include an IsRandom property that determines which one gets returned:
public class MyRandom
{
private static bool _isRandom = false;
private static Random _fixedRandom = new Random(1234);
private static Random _random = new Random();
public static bool IsRandom
{
get
{
return _isRandom;
}
set
{
_isRandom = value;
}
}
public static Random RNG
{
get
{
if (IsRandom)
return _random;
else
return _fixedRandom;
}
}
}
Thanks to #Idle_Mind for their suggestion. Here is a more Delphi-like version:
public static class GlobalRandom
{
private static int _randSeed = 0;
public static Random RNG { get; private set; } = new Random(_randSeed); // Made accessible for Random extensions
public static void Randomize() { RNG = new Random(); }
public static int RandSeed { get => _randSeed;
set { _randSeed = value; RNG = new Random(_randSeed); } }
public static int Next() => RNG.Next();
public static int Next(int minValue, int maxValue) => RNG.Next(minValue, maxValue);
public static int Next(int maxValue) => RNG.Next(maxValue);
public static void NextBytes(byte[] buffer) => RNG.NextBytes(buffer);
public static double NextDouble() => RNG.NextDouble();
}
Use it like:
Console.WriteLine($"Default seed (0): {GlobalRandom.Next()}");
GlobalRandom.Randomize();
Console.WriteLine($"Unknown seed: {GlobalRandom.Next()}");
GlobalRandom.RandSeed = 100;
Console.WriteLine($"Constant seed (100): {GlobalRandom.Next()}");
GlobalRandom.RandSeed = 0;
Console.WriteLine($"Back to default seed: {GlobalRandom.Next()}");
First Run:
Default seed (0): 1559595546
Unknown seed: 1837960504
Constant seed (100): 2080427802
Back to default seed: 1559595546
Second Run:
Default seed (0): 1559595546
Unknown seed: 54655523
Constant seed (100): 2080427802
Back to default seed: 1559595546
So i am creating a dice using a public class called die. this class has 2 constructors and 3 other methods. When i call class within the main program, it will not print the desired (random) result.
Firstly i am trying to print out a random number between 1-6 based on the default values. Once i figure this out, i would eventually like to specify a number of sides for and print out a number between 1 and this specific number.
/// Represents one die (singular of dice) with faces showing values between
/// 1 and the number of faces on the die.
public class Die
{
private int numFaces, faceValue;
public Die() => (numFaces, faceValue) = (6, 1);
public Die(int faces)
{
numFaces = faces;
if (numFaces < 3)
numFaces = 6;
faceValue = 1;
}
public void RollDie()
{
//for (int ctr = 0; ctr <= numFaces; ctr++)
var rnd = new Random();
for (int ctr = 1; ctr <= 20; ctr++)
faceValue = rnd.Next(1, numFaces + 1);
}
public int GetFaceValue() => faceValue;
public int GetNumFaces() => numFaces;
}
public class Program
{
public static void Main()
{
var myDie = new Die(1);
for (int i =0; i < 20; i++)
{
myDie.RollDie();
Console.WriteLine(myDie.GetFaceValue());
}
}
}
Since Random is time seeded when the parameterless constructor is used, this can have the very negative consequence of duplicating results.
Excerpt from the API documentation:
However, because the clock has finite resolution, using the
parameterless constructor to create different Random objects in close
succession creates random number generators that produce identical
sequences of random numbers.
...
On most Windows systems, Random objects created within 15 milliseconds of one another are likely to have identical seed values.
This is a safer approach in regards to getting random numbers when creating and rolling multiple dice:
public class Die
{
static int seed = Environment.TickCount;
static readonly ThreadLocal<Random> DieRandom = new ThreadLocal<Random>(()
=> new Random(Interlocked.Increment(ref seed)));
public int FaceCount { get; }
public int Value { get; private set; }
public Die() : this(6) // default to 6 faces
{
}
public Die(int faceCount)
{
if (faceCount < 3) // validate input
throw new ArgumentOutOfRangeException(nameof(faceCount));
this.FaceCount = faceCount;
}
public int Roll()
{
Value = DieRandom.Next(1, FaceCount + 1);
return Value;
}
}
Edit: updated the Random with thread safety as suggested here.
I'm trying to create my GridData data in an Update/Awake function as a test. But I can't seem to get my constructor working. I'm new to CSharp and Unity. so, I'm a bit stuck here.
GridData Class
[System.Serializable]
public class GridData {
[System.Serializable]
public struct rowData{
public float[] colum;
}
public static int numRows =30;
public static int numColums =20;
public rowData[] rows = new rowData[numRows];
//
//Constructor
public GridData(int x, int y){
numRows =y;
numColums = x;
rowData[] rows = new rowData[numColums];
}
}
FactalMapData Class
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class FractalMapData : MonoBehaviour {
public int gridWidth =20;
public int gridWHight =20;
public GridData fractalGrid ;
void Update () {
//TEST
fractalGrid =new GridData(gridWidth,gridWHight);
Debug.Log ("row" + fractalGrid.rows.Length); //Object reference not set to an instance of an object
Debug.Log ("colum" + fractalGrid.rows[0].colum.Length);//Object reference not set to an instance of an object
}
}
As suggested in my comment, I advise you to actually learn oop before constructing oop code.
But learning by mistakes isn't all that bad, so here the ones you made:
[System.Serializable] // not a mistake, but do you really need this?
public class GridData {
[System.Serializable]
public struct rowData{
public float[] colum;
}
// why are you using a struct with only one field in it
// do you really need a struct?
// PITFALL: you'll be wondering later on, why the values for numRows and numColums are the same for all instances
// Why? Because they are static! That means there are *not* instantiated
public static int numRows =30;
public static int numColums =20;
// You are initializing your rowData here
// and again in the constructor. What do you actually want?
public rowData[] rows = new rowData[numRows];
//
//Constructor
public GridData(int x, int y){
// As mentioned before:
// you are assigning instantiating values to static fields
numRows =y;
numColums = x;
// you are *defining* a local variable called rows and initializing it with an array of length numColums
// After we leave the constructor this get's lost
rowData[] rows = new rowData[numColums];
}
}
Another thing you should think about: Why are you creating a class
If you find, that you have a good reason, ask yourself what the responsibility of the class is. E.g.: Should it just hold some data, Does it provide any abstraction, Will it manipulate the data it has, should the data be exposed?
I think you have not answered most of these questions.
Here is how it could work
"I need a class that holds some grid data"
"I want the underlying data structure to be a one dimensional array" (for whatever reason)
"The abstraction is, that the class exposes the data as a two dimensional grid"
"I don't need to initialize the class with existing data" (for now)
Then you can implement the class
public class GridData {
// The concrete data doesn't have to be exposed
// let's make it private
private float[] data;
// let's use properties for this (= less code)
// get; means it's accessible as defined at the beginning (public)
// private set; means only the class it self can change these numbers
public int RowCount { get; private set; }
public int ColCount { get; private set; }
// I want to represent the data as a 2D grid so let's make a function
public float GetCell(int x, int y) {
// validate requests!
if(
x >= ColCount || x < 0
||
y >= RowCount || y < 0
) {
// don't be shy to throw exceptions!
// they communicate exceptional circumstances!
throw new ArgumentOutOfRangeException("Requested cell is not on grid");
}
return data[y * RowCount + x];
}
// I want the data to be set from outside
public float SetCell(int x, int y, float value) {
// excercise for you!
}
public GridData(int cols, int rows) {
RowCount = rows;
ColCount = cols;
this.data = new float[rows * cols];
}
}
Note that there are multiple ways to implement a class that conforms to the needs I formulated.
You never initialize public float[] colum; anywhere in your code.
As a result, when you invoke your constructor, although you correctly create an initialized rows array, the colum field of each rowData instance has not been initialized and will throw a null reference exception when trying to access the length of the collection.
public GridData(int x, int y){
numRows =y;
numColums = x;
rowData[] rows = new rowData[numColums]; // BUG HERE
}
Here you are declaring a LOCAL variable rows, with the same name as the instance field named rows. Thus the instance field rows is never assigned.
You mean:
public GridData(int x, int y){
numRows =y;
numColums = x;
rows = new rowData[numColums];
}
"Create a program named "DemoSquare" that initiates an array of 10 Square objects with sides that have values of 1 -10 and that displays the values for each square. The Square class contains fields for the area and the length of a side, and a constructor that requires a parameter for the area and the length of a side. The constructor assigns its parameter to the length of a Square's side and calls a private method that computes the area field. Also include read-only properties to get a Squares side and area."
Now I think that it is a trick question as I can't get the private method to compute the area because of the read-only assignment but here is my code:
class demoSquares
{
static void Main(string[] args)
{
Square[] squares = new Square[10];//Declares the array of the object type squares
for (int i = 0; i < 10; i++)
{
//Console.WriteLine("Enter the length");
//double temp = Convert.ToDouble(Console.ReadLine());
squares[i] = new Square(i+1);//Initializes the objects in the array
}
for (int i = 0; i < 10; i++)
{
Console.WriteLine(squares[i]);
}//end for loop, prints the squares
}//end main
}//end class
This is the Square Class:
public class Square
{
readonly double length;
readonly double area;
public Square(double lengths)//Constructor
{
length = lengths;
area = computeArea();
}
private double computeArea()//getmethod
{
double areaCalc = length * length;
return areaCalc;
}
}
Don't confuse read-only properties with read-only fields.
public class Square
{
public Square(double lengths)
{
Length = lengths;
Area = computeArea();
}
//Read only property for Length (privately settable)
public double Length {get; private set;}
//Read only property for Area (privately settable)
public double Area {get; private set;}
//Private method to compute area.
private double ComputeArea()
{
return Length * Length;
}
}
A read-only variable can indeed be assigned in the constructor, but not in methods called from the constrctor. There are ways to do that, i.e. : link. The correct way would be to calculate the area and store the result in the area variable.
I believe, though, that the meaning was different in the question. Quoting you :
Also include read-only properties to get a Squares side and area.
meaning, the question meant that you use Properties. Meaning, you would use private variables for length and area, and implement a get-only property for each :
public double Area
{
get
{
return area;
}
}
The question mentions readonly properties, not readonly fields.
a readonly field can only be assigned in a constructor or by a field initializer.
A readonly property can only be assigned inside the class.
public class Square
{
// Readonly field, can only be assigned in constructor or initializer
private readonly double _sideLength;
// Readonly property since it only contains a getter
public double SideLength { get { return _sideLength; } }
// Readonly property from outside the class since the setter is private
public double Area {get; private set;}
public Square( double sideLength )
{
_sideLength = sideLength;
CalcSquare();
}
private void CalcSquare()
{
this.Square = _sideLength * _sideLength;
}
}
Consider how you would restructure the code if you didn't try to assign the computed area to the area field, but instead returned the value from computeArea.
As an additional exercise, try making computeArea static and see how that affects the code.
You assignment never said your private function should assign area. It said the constructor should assign area with the result of a private method:
public class Square
{
private readonly double length;
private readonly double area;
public Square(double length)
{
this.length = length;
this.area = computeArea(length); // assignment of area in constructor!
}
private double ComputeArea(double length)
{
return length * length;
}
}
Is C#'s Random.Next() method thread safe?
No, using the same instance from multiple threads can cause it to break and return all 0's. However, creating a thread-safe version (without needing nasty locks on every call to Next()) is simple. Adapted from the idea in this article:
public class ThreadSafeRandom
{
private static readonly Random _global = new Random();
[ThreadStatic] private static Random _local;
public int Next()
{
if (_local == null)
{
int seed;
lock (_global)
{
seed = _global.Next();
}
_local = new Random(seed);
}
return _local.Next();
}
}
The idea is to keep a separate static Random variable for each thread. Doing that in the obvious way fails, however, because of another issue with Random - if multiple instances are created at nearly the same time (within about 15ms), they will all return the same values! To fix this, we create a globally-static Random instance to generate the seeds used by each thread.
The above article, by the way, has code demonstrating both of these issues with Random.
There's nothing special done in the Next method to achieve thread safety. However, it's an instance method. If you don't share instances of Random across different threads, you don't have to worry about state corruption within an instance. Do not use a single instance of Random across different threads without holding an exclusive lock of some sort.
Jon Skeet has a couple nice posts on this subject:
StaticRandom
Revisiting randomness
As noted by some commentators, there is another potential problem in using different instances of Random that are thread-exclusive, but are seeded identically, and therefore induce the identical sequences of pseudorandom numbers, because they may be created at the same time or within close temporal proximity of each other. One way to alleviate that issue is to use a master Random instance (which is locked by a single thread) to generate some random seeds and initialize new Random instances for every other thread to use.
The offical answer from Microsoft is a very strong no. From http://msdn.microsoft.com/en-us/library/system.random.aspx#8:
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.
As described in the docs, there is a very nasty side effect that can happen when the same Random object is used by multiple threads: it just stops working.
(i.e. there is a race condition which when triggered, the return value from the 'random.Next....' methods will be 0 for all subsequent calls.)
No, it's not thread safe. If you need to use the same instance from different threads, you have to synchronise the usage.
I can't really see any reason why you would need that, though. It would be more efficient for each thread to have their own instance of the Random class.
Another thread safe way is to use ThreadLocal<T> as follows:
new ThreadLocal<Random>(() => new Random(GenerateSeed()));
The GenerateSeed() method will need to return a unique value each time it is called to assure that the random number sequences are unique in each thread.
static int SeedCount = 0;
static int GenerateSeed() {
return (int) ((DateTime.Now.Ticks << 4) +
(Interlocked.Increment(ref SeedCount)));
}
Will work for small numbers of threads.
Is C#'s Random.Next() method thread safe?
As was written before, anwer is No. However, starting from .NET6, we have out of box thread-safe alternative: Random.Shared.Next();
See details here: https://learn.microsoft.com/en-us/dotnet/api/system.random.shared?view=net-6.0
For what its worth, here is a thread-safe, cryptographically strong RNG that inherits Random.
The implementation includes static entry points for ease of use, they have the same names as the public instance methods but are prefixed with "Get".
A call to the RNGCryptoServiceProvider.GetBytes is a relatively expensive operation. This is mitigated through the use of an internal buffer or "Pool" to make less frequent, and more efficient use of RNGCryptoServiceProvider. If there are few generations in an application domain then this could be viewed as overhead.
using System;
using System.Security.Cryptography;
public class SafeRandom : Random
{
private const int PoolSize = 2048;
private static readonly Lazy<RandomNumberGenerator> Rng =
new Lazy<RandomNumberGenerator>(() => new RNGCryptoServiceProvider());
private static readonly Lazy<object> PositionLock =
new Lazy<object>(() => new object());
private static readonly Lazy<byte[]> Pool =
new Lazy<byte[]>(() => GeneratePool(new byte[PoolSize]));
private static int bufferPosition;
public static int GetNext()
{
while (true)
{
var result = (int)(GetRandomUInt32() & int.MaxValue);
if (result != int.MaxValue)
{
return result;
}
}
}
public static int GetNext(int maxValue)
{
if (maxValue < 1)
{
throw new ArgumentException(
"Must be greater than zero.",
"maxValue");
}
return GetNext(0, maxValue);
}
public static int GetNext(int minValue, int maxValue)
{
const long Max = 1 + (long)uint.MaxValue;
if (minValue >= maxValue)
{
throw new ArgumentException(
"minValue is greater than or equal to maxValue");
}
long diff = maxValue - minValue;
var limit = Max - (Max % diff);
while (true)
{
var rand = GetRandomUInt32();
if (rand < limit)
{
return (int)(minValue + (rand % diff));
}
}
}
public static void GetNextBytes(byte[] buffer)
{
if (buffer == null)
{
throw new ArgumentNullException("buffer");
}
if (buffer.Length < PoolSize)
{
lock (PositionLock.Value)
{
if ((PoolSize - bufferPosition) < buffer.Length)
{
GeneratePool(Pool.Value);
}
Buffer.BlockCopy(
Pool.Value,
bufferPosition,
buffer,
0,
buffer.Length);
bufferPosition += buffer.Length;
}
}
else
{
Rng.Value.GetBytes(buffer);
}
}
public static double GetNextDouble()
{
return GetRandomUInt32() / (1.0 + uint.MaxValue);
}
public override int Next()
{
return GetNext();
}
public override int Next(int maxValue)
{
return GetNext(0, maxValue);
}
public override int Next(int minValue, int maxValue)
{
return GetNext(minValue, maxValue);
}
public override void NextBytes(byte[] buffer)
{
GetNextBytes(buffer);
}
public override double NextDouble()
{
return GetNextDouble();
}
private static byte[] GeneratePool(byte[] buffer)
{
bufferPosition = 0;
Rng.Value.GetBytes(buffer);
return buffer;
}
private static uint GetRandomUInt32()
{
uint result;
lock (PositionLock.Value)
{
if ((PoolSize - bufferPosition) < sizeof(uint))
{
GeneratePool(Pool.Value)
}
result = BitConverter.ToUInt32(
Pool.Value,
bufferPosition);
bufferPosition+= sizeof(uint);
}
return result;
}
}
Since Random isn't thread-safe, you should have one per thread, rather than a global instance. If you're worried about these multiple Random classes being seeded at the same time (i.e. by DateTime.Now.Ticks or such), you can use Guids to seed each of them. The .NET Guid generator goes to considerable lengths to ensure non-repeatable results, hence:
var rnd = new Random(BitConverter.ToInt32(Guid.NewGuid().ToByteArray(), 0))
Reimplementation of BlueRaja's answer using ThreadLocal:
public static class ThreadSafeRandom
{
private static readonly System.Random GlobalRandom = new Random();
private static readonly ThreadLocal<Random> LocalRandom = new ThreadLocal<Random>(() =>
{
lock (GlobalRandom)
{
return new Random(GlobalRandom.Next());
}
});
public static int Next(int min = 0, int max = Int32.MaxValue)
{
return LocalRandom.Value.Next(min, max);
}
}
Per documentation
Any public static (Shared in Visual Basic) members of this type are thread safe. Any instance members are not guaranteed to be thread safe.
http://msdn.microsoft.com/en-us/library/system.random.aspx
Here is a simple solution that doesn't involve creating classes. Hides everything inside an ad-hoc lambda:
private static Func<int, int, int> GetRandomFunc()
{
Random random = new Random();
object lockObject = new object();
return (min, max) =>
{
lock (lockObject)
{
return random.Next(min, max);
}
};
}
In any class that needs a thread safe random generator define
private static readonly Func<int, int, int> GetRandomNext = GetRandomFunc();
Then use it freely inside your class:
int nextRandomValue = GetRandomNext(0, 10);
The radndom function can have different signatures depending what is needed. e.g.
private static Func<int> GetRandomFunc()
{
Random random = new Random();
object lockObject = new object();
return () =>
{
lock (lockObject)
{
return random.Next();
}
};
}
For a thread safe random number generator look at RNGCryptoServiceProvider. From the docs:
Thread Safety
This type is thread safe.
I just created Random instance on a load of threads simultaneously and got unexpected patterns from the results because, presumably, all the seeds were the same.
My solution was to create a thread safe class -
public class StaticRandom
{
static Random rnd = new Random();
public static int GetNext()
{
// random is not properly thread safe
lock(rnd)
{
return rnd.Next();
}
}
}
And then, create a new Random object instance for each thread -
// Take this threads instance seed from the static global version
Random rnd = new Random(StaticRandom.GetNext());
Here's an efficient solution using ThreadLocal:
public class ThreadSafeRandom
{
private static readonly Random _global = new Random();
private static readonly ThreadLocal<Random> _local = new ThreadLocal<Random>(() =>
{
int seed;
lock (_global)
{
seed = _global.Next();
}
return new Random(seed);
});
public static Random Instance => _local.Value;
}
To use, replace:
var random = new Random();
var myNum = random.Next();
With:
var myNum = ThreadSafeRandom.Instance.Next();
This solution has been packaged as a NuGet package with source available on GitHub.
EDIT: Since .NET 6.0 you can use Random.Shared.Next() instead. You can still use the above package which chooses between the above code or Random.Shared with preprocessor directives.
Here is an expanded version of BlueRaja's answer as a static class with comments and all public Random members implemented.
/// <summary>
/// A pseudo-random number generator based on <see cref="Random"/>, but with the following enhancements:
/// <list type="number">
/// <item>Can be safely used from any thread without defaulting to 0.</item>
/// <item>Repeated calls from different threads do not tend to generate identical sequences.</item>
/// </list>
/// </summary>
public static class ThreadSafeRandom
{
private static readonly Random _globalSeeder = new Random();
/// <summary>
/// Holds a separate <see cref="Random"/> instance for each thread.
/// </summary>
[ThreadStatic] private static Random _threadStaticInstance;
/// <summary>
/// Seeds each thread's <see cref="_threadStaticInstance"/> with <see cref="_globalSeeder"/>'s <see cref="Random.Next()"/>.
/// Simply using <see langword="new"/> <see cref="Random()"/> would cause a problem where,
/// if multiple threads' <see cref="Random"/> instances were constructed very close in time,
/// they would end up with the same seed, and therefore identical sequences.
/// </summary>
private static Random GetThreadStaticInstance()
{
if (_threadStaticInstance == null)
{
int seed;
lock (_globalSeeder)
{
seed = _globalSeeder.Next();
}
_threadStaticInstance = new Random(seed);
}
return _threadStaticInstance;
}
/// <inheritdoc cref="Random.Next()"/>
public static int Next() => GetThreadStaticInstance().Next();
/// <inheritdoc cref="Random.Next(int, int)"/>
public static int Next(int minValue, int maxValue) => GetThreadStaticInstance().Next(minValue, maxValue);
/// <inheritdoc cref="Random.Next(int)"/>
public static int Next(int maxValue) => GetThreadStaticInstance().Next(maxValue);
/// <inheritdoc cref="Random.NextDouble()"/>
public static double NextDouble() => GetThreadStaticInstance().NextDouble();
/// <inheritdoc cref="Random.NextBytes(byte[])"/>
public static void NextBytes(byte[] buffer) => GetThreadStaticInstance().NextBytes(buffer);
UPDATED: It is not. You need to either reuse an instance of Random on each consecutive call with locking some "semaphore" object while calling the .Next() method or use a new instance with a guaranteed random seed on each such call. You can get the guaranteed different seed by using cryptography in .NET as Yassir suggested.
The traditional thread local storage approach can be improved upon by using a lock-less algorithm for the seed. The following was shamelessly stolen from Java's algorithm (possibly even improving on it):
public static class RandomGen2
{
private static readonly ThreadLocal<Random> _rng =
new ThreadLocal<Random>(() => new Random(GetUniqueSeed()));
public static int Next()
{
return _rng.Value.Next();
}
private const long SeedFactor = 1181783497276652981L;
private static long _seed = 8682522807148012L;
public static int GetUniqueSeed()
{
long next, current;
do
{
current = Interlocked.Read(ref _seed);
next = current * SeedFactor;
} while (Interlocked.CompareExchange(ref _seed, next, current) != current);
return (int)next ^ Environment.TickCount;
}
}