Что вам нужно, так это лучший способ начать заполнение в вашем приложении ASP.NET, качество Random должно быть в порядке, используя метод ниже.
public static int GenerateRandomValueDefault(int irRandValRange)//default min val 1
{
return GenerateRandomValueMin(irRandValRange, 1);
}
public static int GenerateRandomValueMin(int irRandValRange, int irMinValue)
{
Random rand = GetRandom();
return rand.GetNext(irMinValue,irRandValRange)
}
//This is a global random number generator, it is only used to provide the seed for the local RNG's.
private static Random GlobalRandom = new Random();
private static Random GetRandom()
{
if (HttpContext.Current.Session["RNG"] == null)
{
//This lock is only hit the very first time the users Session state is used, every time after that it should use the cached local copy without taking the lock.
lock(GlobalRandom)
{
//We use the Global RNG for seed instead of the default because it uses time to seed by default, and if two people get a new Random() within the same time-slice they will have the same seed. This prevents that from happening.
HttpContext.Current.Session["RNG"] = new Random(GlobalRandom.Next());
}
}
//Return the cached/new RNG.
return (Random)HttpContext.Current.Session["RNG"];
}
У вас есть один экземпляр глобальной RNG, который блокируется, однако он срабатывает только при создании нового состояния сеанса, после чего сеанс использует только свою локальную копию. Вы получите очень хорошую производительность во время выполнения с небольшой нагрузкой при загрузке первой страницы на человека, поскольку она генерирует одно число из глобального хранилища.
Вы можете изменить это в соответствии со своими потребностями, но это даст вам общее представление, но даст общее представление.
Согласно предложению Хенка Холтермана, вот решение без блокировки, которое может быть быстрее и не использует HttpState.
private static int SeedCounter = 0;
private readonly object SeedInitLock = new Object();
private static Random GetRandom()
{
//Do init the first time this function is ever called.
if(SeedCounter == -1)
{
//The first time the function is called everyone will try to update SeedCounter, but only the first
//thread to complete it will be the value everyone uses.
Random initRNG = new Random();
Interlocked.CompareExchange(ref SeedCounter, initRNG.Next(), -1);
}
else if (SeedCounter < 0)
{
//Because Interlocked.Increment wraps the value to int.MinValue and Random(int) will take the absolute
//value of the seed, we skip all of the negitive numbers and go to 0.
Interlocked.CompareExchange(ref SeedCounter, 0, int.MinValue);
}
int tempSeed = Interlocked.Increment(ref SeedCounter);
if (tempSeed < 0)
{
//If tempSeed is negative we hit a edge case where SeedCounter wrapped around. We just call the function
//again so we do not reuse a seed that was just used.
return GetRandom();
}
return new Random(tempSeed);
}