Reputation: 105
In VB.net, I have a function which generates a random string of integer numbers
Public Function RandomString(ByVal Size As Integer, ByVal LowerBound As Double, ByVal Upperbound As Double) As list (of integer)
It gets three factors (size, lowerBound and upperBound) and generates a random list of length "size" each value randomly between "LowerBound" and "UpperBound"
In my code at the top I have:
Imports System.Random
And the body of the function goes like this:
Dim rand As New Random
Dim mystr as new list (of integer)
for i as integer=1 to size
mystr.add(rand.Next(Upperbound - LowerBound + 1) + LowerBound)
next
return mystr
Inside my sub I have:
dim MyData(10) as list (of integer)
for i as integer = 0 to 9
mydata(i) = new list (of integer)
mydata(i) = RandomString(5,2,4)
next
The strange problem is that when I run this normally , it generates 10 strings exactly the same values.
For example like this:
2,3,3,2,4
2,3,3,2,4
2,3,3,2,4
...
But when i put a toggle stop point inside the loop (loop inside my sub) and I run the code step by step, it work correctly and generates different strings as intended. such as
2,3,2,4,3
3,2,4,4,2
4,3,3,2,2
...
Why does this happen? How should I modify it to work correctly in a normal run?
Upvotes: 2
Views: 440
Reputation: 8475
@Renan's answer is correct. You can also do the following, which initializes the variable only once but should give you uniqueness during multiple calls.
Static rand As New Random
Upvotes: 1
Reputation: 564363
The problem is that, by default, System.Random
will seed itself based off the current time. If you create multiple instances in a very short period of time (such as a loop), you'll get the same seed, which will in turn create the same sequence.
You can avoid this by making your Random instance Static
:
Public Function RandomString(ByVal Size As Integer, ByVal LowerBound As Double, ByVal Upperbound As Double) As List(of Integer)
' Static makes this instance get "preserved" across multiple calls to the method
' So it's only created once
Static rand As New Random
Dim mystr as new List(of Integer)
For i as integer=1 to size
mystr.add(rand.Next(Upperbound - LowerBound + 1) + LowerBound)
next
return mystr
End Function
This will cause the same instance to be used across multiple calls, which in turn will cause it to not re-seed with the same seed. Note that this will not be thread safe, however, if you use this method from multiple threads.
Upvotes: 1
Reputation: 9399
When you create an instance of Random, if you don't pass the seed you wish to use, it will use a default one that is time dependent. From the official documentation:
The default seed value is derived from the system clock and has finite resolution. As a result, different Random objects that are created in close succession by a call to the default constructor will have identical default seed values and, therefore, will produce identical sets of random numbers.
Which is why you get a "more random" result when you debug it - you are giving more time between instantiations.
So either use different seeds for each instance, or artificially give more time between each instantiation (i.e.: Thread.Sleep
, but this is a very ugly hack).
Upvotes: 2