Jedes Mal, wenn Sie dies tun, wird new Random()es mit der Uhr initialisiert. Dies bedeutet, dass Sie in einer engen Schleife oft den gleichen Wert erhalten. Sie sollten eine einzelne Zufallsinstanz beibehalten und Next auf derselben Instanz verwenden.
//Function to get a random number
private static readonly Random random = new Random();
private static readonly object syncLock = new object();
public static int RandomNumber(int min, int max)
{
lock(syncLock) { // synchronize
return random.Next(min, max);
}
}
Bearbeiten (siehe Kommentare): Warum brauchen wir lockhier ein?
Grundsätzlich Nextwird sich der interne Status der RandomInstanz ändern . Wenn wir dies gleichzeitig aus mehreren Threads heraus tun, könnten Sie argumentieren, "wir haben das Ergebnis nur noch zufälliger gemacht", aber was wir tatsächlich tun, ist möglicherweise, die interne Implementierung zu brechen, und wir könnten auch anfangen, die gleichen Zahlen zu erhalten von verschiedenen Threads, die möglicherweise ein Problem sein - und vielleicht nicht. Die Garantie dafür, was intern passiert, ist jedoch das größere Problem. da Randomsich nicht machen keine Garantien für Thread-Sicherheit. Somit gibt es zwei gültige Ansätze:
- Synchronisieren Sie, damit wir nicht gleichzeitig von verschiedenen Threads darauf zugreifen
- Verwenden Sie unterschiedliche
RandomInstanzen pro Thread
Beides kann in Ordnung sein; Das Stummschalten einer einzelnen Instanz von mehreren Anrufern gleichzeitig ist jedoch nur ein Problem .
Das lockerreicht den ersten (und einfacheren) dieser Ansätze; Ein anderer Ansatz könnte jedoch sein:
private static readonly ThreadLocal<Random> appRandom
= new ThreadLocal<Random>(() => new Random());
Dies ist dann pro Thread, sodass Sie nicht synchronisieren müssen.
new Random().Next((int)0xFFFF, (int)0xFFFFFF) % 256);ergibt keine besseren "Zufallszahlen" als.Next(0, 256)