I am trying to get 3 random numbers which works fine within a Windows app but not in a Web app.
Protected Function GetNextPhoto(intMaxPics As Integer) As Integer
Dim rnd As New Random
Dim intRandom As Integer
intRandom = rnd.Next(1, intMaxPics)
Return intRandom
End Function
or
Private Function GetAnotherNumber(i As Integer) As Integer
Dim r As New Random
Dim ii As Integer = r.Next(i)
Return ii
End Function
If I do:
Dim intPic As Integer = GetAnotherNumber(22)
I get the first random number - great.
If I then do:
intPic = 0
intPic = GetAnotherNumber(22)
to generate another random number I get the same number I originally had. The same thing happens for all three so it's not random. If I refresh the page the same number is again returned 3 times, and so on.
Move the declaration of the random number generator out of the loop.
Please try to modify your method like given below
Private Shared ReadOnly r As New Random()
Public Function GetAnotherNumber(i As Integer) As Integer
Dim ii As Integer = r.[Next](i)
Return ii
End Function
Random works off of a "seed" which is a random number sequence based on using that seed with an equation. So if you create Random(1) and ask for 5 numers you'll always get the same sequence. If you fo Random(10) you'll also get the same sequence every
time, though a different sequence from Random(5).
Just Random on its own uses a time-based seed, so if you create new copies of Random very quickly they'll have the same seed so give the same answers. If you need 3 numbers and create new Random for each number you'll get the same 3 numbers. What you have
to do is create just one instance of Random, and use that same instance to get the next 3 numbers.
So, basically, GetAnotherNumber when called in quick succession will usually give the same number each time as it is using the same seed. If you want three numbers then add a parameter to your function that says how many numbers you want, and make your
function return a List<int> of three numbers using the same instance of Random.
randomvb.netasp.net
I'm afraid I no longer use this forum due to the new point allocation system.
Use a single Random object rather than creating a new one each time. If you create them too quickly you actually create 3 times the same sequence (as generated values are time dependent) and just consume the first value (which will be the same for all 3
sequences).
Instead, if you create a single Random object, you'll create a single sequence of random numbers and will consume the first 3 values which will be all different...
You need to use
SyncLock to stop this repeating behaviour ..
Public Shared Function GetRandomNumber(minValue As Integer, maxValue As Integer) As Integer
SyncLock synchLock
Thread.Sleep(100)
Return random.[Next](minValue, maxValue)
End SyncLock
End Function
There is no need to sleep for this to work. All you're doing is massively increasing your resources and decreasing the scalability of your site. Your whole page should take about 50ms or less to process, and if you want 5 random numbers your page is going
to take 500ms minimum. Now imaging 1,000 people are browsing your site.
Above is just an example.. Obviously he wouldn't use thread sleep on his page. :)
Note:If you are going to create more than one random number, you should keep the Random instance and reuse it. If you create new instances too close in time, they will produce the same series of random numbers as the random generator is
seeded from the system clock.
Many thanks for all your replies. From such a simple post I have learnt a lot - thank you all
I found when I used the synchlock example there were more chances of getting 2 of the same number and was thinking that the random function was truly random but it is possible to predict the outcome as one reply basically mentioned.
What I will do now is play around with the synchlock code for numbers from 1 - 21, 000 and use the code where one reply moved the 'New Random' outside the function for the smaller numbers
Never knew about synchlock as I have been out of coding around 6 years so will look into that on MSDN more because that could resolve another issue I was experiencing in another class and never went back to - fingers crossed
Thank you once again for all the replies, advice, code & help
You need to use
SyncLock to stop this repeating behaviour ..
Public Shared Function GetRandomNumber(minValue As Integer, maxValue As Integer) As Integer
SyncLock synchLock
Thread.Sleep(100)
Return random.[Next](minValue, maxValue)
End SyncLock
End Function
There is no need to sleep for this to work. All you're doing is massively increasing your resources and decreasing the scalability of your site. Your whole page should take about 50ms or less to process, and if you want 5 random numbers your page is going
to take 500ms minimum. Now imaging 1,000 people are browsing your site.
randomvb.netasp.net
I'm afraid I no longer use this forum due to the new point allocation system.
In my opinion this is really a bad way to solve the problem. It doesn't solve the real issue but instead it adds some code to counter its effect.
Once again the real problem is that you create 3 times the same sequence of random numbers and consuming only the first value which is always the same (because they are initialized based on the time and you care creating them in close succession you end
up 3 times with the same series of random numbers).
Instead you should create a single sequence of random numbers and consume 3 values from this sequence. See :
Random r;
// Bad
for(int i=1;i<=3;i++)
{
r=new Random(); // Same sequence
System.Diagnostics.Debug.WriteLine(r.Next(100)); // First value
}
// Good
r=new Random(); // Single sequence
for(int i=1;i<=3;i++)
{
System.Diagnostics.Debug.WriteLine(r.Next(100)); // First, second, third value of a single sequence
}
Values are shown in the debugger output window...
(Sorry I'm using both VB and C# and realized you are using VB, this is the same problem anyway ie. creating 3 sequences in close succession and using the first value, rather than creating a single sequence and consuming the first 3 values).
I understand your point but when I tested it with numbers 1 - 20 (GetRandomNumber(1, 20)), 3 of the 4 times two numbers were the same compared to 1 in 7'ish without synchlock. Maybe when I scale it up the possibilities are going to be far less like with
the lottery.
You make a very good point about not making the thread sleep and that noticeable difference would be picked-up with Googlebot too. Although, I remember that you shouldn't use Thread.Sleep in a web app but use a different method of sleeping the thread (same
thing but a different way for web apps). Not to worry, as it wouldn't be used given your argument of page speed.
It's not the lock that is doing it, it's the sleep that is ensuring each time random is created that it has a different seed. You should just generate the numbers you need in one go;
protected void Page_Load(object sender, EventArgs e)
{
System.Diagnostics.Debug.WriteLine(string.Join(",", GetRandomNumber(10, 3)));
}
public IEnumerable<int> GetRandomNumber(int max, int count)
{
Random r = new Random();
for (int i = 0; i < count; i++)
{
yield return r.Next(max);
}
}
Or if you need to do it right after another, don't use the time-based seed.
protected void Page_Load(object sender, EventArgs e)
{
int? last = null;
for (int i = 0; i < 5; i++)
{
last = GetRandomNumber(10, last);
System.Diagnostics.Debug.WriteLine(last);
}
}
public int GetRandomNumber(int max, int? seed = null)
{
Random r = seed.HasValue ? new Random(seed.Value) : new Random();
return r.Next(max);
}
randomvb.netasp.net
I'm afraid I no longer use this forum due to the new point allocation system.
Member
104 Points
319 Posts
Random Number Not Random
Aug 25, 2013 03:33 PM|crouchie2004|LINK
Hi,
VB.NET 2012 using Framework 4.5
I am trying to get 3 random numbers which works fine within a Windows app but not in a Web app.
or
If I do:
I get the first random number - great.
If I then do:
to generate another random number I get the same number I originally had. The same thing happens for all three so it's not random. If I refresh the page the same number is again returned 3 times, and so on.
Any ideas how I can resolve this?
Thanks
random vb.net asp.net
All-Star
50841 Points
9895 Posts
Re: Random Number Not Random
Aug 25, 2013 03:39 PM|A2H|LINK
Hi,
Move the declaration of the random number generator out of the loop.
Please try to modify your method like given below
Refer this link for more details
random vb.net asp.net
Aje
My Blog | Dotnet Funda
All-Star
37441 Points
9076 Posts
Re: Random Number Not Random
Aug 25, 2013 03:41 PM|AidyF|LINK
Random works off of a "seed" which is a random number sequence based on using that seed with an equation. So if you create Random(1) and ask for 5 numers you'll always get the same sequence. If you fo Random(10) you'll also get the same sequence every time, though a different sequence from Random(5).
Just Random on its own uses a time-based seed, so if you create new copies of Random very quickly they'll have the same seed so give the same answers. If you need 3 numbers and create new Random for each number you'll get the same 3 numbers. What you have to do is create just one instance of Random, and use that same instance to get the next 3 numbers.
So, basically, GetAnotherNumber when called in quick succession will usually give the same number each time as it is using the same seed. If you want three numbers then add a parameter to your function that says how many numbers you want, and make your function return a List<int> of three numbers using the same instance of Random.
random vb.net asp.net
All-Star
48730 Points
18189 Posts
Re: Random Number Not Random
Aug 25, 2013 03:43 PM|PatriceSc|LINK
Hi,
Use a single Random object rather than creating a new one each time. If you create them too quickly you actually create 3 times the same sequence (as generated values are time dependent) and just consume the first value (which will be the same for all 3 sequences).
Instead, if you create a single Random object, you'll create a single sequence of random numbers and will consume the first 3 values which will be all different...
random vb.net asp.net
Star
13450 Points
2764 Posts
Re: Random Number Not Random
Aug 25, 2013 03:46 PM|Nasser Malik|LINK
You need to use SyncLock to stop this repeating behaviour ..
http://revenmerchantservices.com/post/C-Generate-Random-Number.aspx
Above is just an example.. Obviously he wouldn't use thread sleep on his page. :)
Note:If you are going to create more than one random number, you should keep the Random instance and reuse it. If you create new instances too close in time, they will produce the same series of random numbers as the random generator is seeded from the system clock.
http://stackoverflow.com/questions/2706500/how-to-generate-random-int-number-c
random vb.net asp.net
Skype: maleknasser1
LinkedIn: https://www.linkedin.com/in/maliknasser
Member
104 Points
319 Posts
Re: Random Number Not Random
Aug 25, 2013 04:10 PM|crouchie2004|LINK
Many thanks for all your replies. From such a simple post I have learnt a lot - thank you all
I found when I used the synchlock example there were more chances of getting 2 of the same number and was thinking that the random function was truly random but it is possible to predict the outcome as one reply basically mentioned.
What I will do now is play around with the synchlock code for numbers from 1 - 21, 000 and use the code where one reply moved the 'New Random' outside the function for the smaller numbers
Never knew about synchlock as I have been out of coding around 6 years so will look into that on MSDN more because that could resolve another issue I was experiencing in another class and never went back to - fingers crossed
Thank you once again for all the replies, advice, code & help
random vb.net asp.net
All-Star
37441 Points
9076 Posts
Re: Random Number Not Random
Aug 25, 2013 04:36 PM|AidyF|LINK
There is no need to sleep for this to work. All you're doing is massively increasing your resources and decreasing the scalability of your site. Your whole page should take about 50ms or less to process, and if you want 5 random numbers your page is going to take 500ms minimum. Now imaging 1,000 people are browsing your site.
random vb.net asp.net
All-Star
48730 Points
18189 Posts
Re: Random Number Not Random
Aug 25, 2013 04:55 PM|PatriceSc|LINK
In my opinion this is really a bad way to solve the problem. It doesn't solve the real issue but instead it adds some code to counter its effect.
Once again the real problem is that you create 3 times the same sequence of random numbers and consuming only the first value which is always the same (because they are initialized based on the time and you care creating them in close succession you end up 3 times with the same series of random numbers).
Instead you should create a single sequence of random numbers and consume 3 values from this sequence. See :
Values are shown in the debugger output window...
(Sorry I'm using both VB and C# and realized you are using VB, this is the same problem anyway ie. creating 3 sequences in close succession and using the first value, rather than creating a single sequence and consuming the first 3 values).
random vb.net asp.net
Member
104 Points
319 Posts
Re: Random Number Not Random
Aug 25, 2013 04:56 PM|crouchie2004|LINK
Hi,
I understand your point but when I tested it with numbers 1 - 20 (GetRandomNumber(1, 20)), 3 of the 4 times two numbers were the same compared to 1 in 7'ish without synchlock. Maybe when I scale it up the possibilities are going to be far less like with the lottery.
You make a very good point about not making the thread sleep and that noticeable difference would be picked-up with Googlebot too. Although, I remember that you shouldn't use Thread.Sleep in a web app but use a different method of sleeping the thread (same thing but a different way for web apps). Not to worry, as it wouldn't be used given your argument of page speed.
random vb.net asp.net
All-Star
37441 Points
9076 Posts
Re: Random Number Not Random
Aug 25, 2013 07:46 PM|AidyF|LINK
It's not the lock that is doing it, it's the sleep that is ensuring each time random is created that it has a different seed. You should just generate the numbers you need in one go;
Or if you need to do it right after another, don't use the time-based seed.
random vb.net asp.net