Randomization in VB.Net

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

Answers (3)

ps2goat
ps2goat

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

Reed Copsey
Reed Copsey

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

Geeky Guy
Geeky Guy

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

Related Questions