Chaque fois que vous effectuez new Random()
il est initialisé à l'aide de l'horloge. Cela signifie que dans une boucle serrée, vous obtenez la même valeur beaucoup de temps. Vous devriez garder un seul Random
exemple et continuer à l'utiliser Next
sur la même instance.
//Function to get 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);
}
}
Edit (voir les commentaires): pourquoi avons-nous besoin d'un lock
ici?
Fondamentalement, Next
, un changement de l'état interne de l' Random
de l'instance. Si nous faisons cela en même temps à partir de plusieurs threads, vous pourriez dire "nous avons juste fait le résultat encore plus aléatoire", mais ce que nous sommes réellement en train de faire est potentiellement casser la mise en œuvre interne, et nous pourrions aussi commencer à obtenir le même nombre de threads différents, ce qui pourrait être un problème - et peut-être pas. La garantie de ce qui se passe en interne est le plus gros problème, cependant, depuis Random
ne pas faire toutes les garanties de fil de sécurité. Il y a donc deux approches valables:
- synchroniser, de sorte que nous n'avons pas accès à la fois à partir de différents threads
- utiliser différents
Random
cas par thread
peut-être bien; mais la mutation d'un seul exemple de plusieurs appelants en même temps c'est juste des ennuis.
L' lock
réalise la première (et plus simple) de ces approches; cependant, une autre approche pourrait être:
private static readonly ThreadLocal<Random> appRandom
= new ThreadLocal<Random>(() => new Random());
c'est ensuite par thread, de sorte que vous n'avez pas besoin de synchroniser.