This happens because of the following scenario:
- You generate a random number
- Suppose none of the conditions in the first
if
is met, else
clause is executed
currentTrack
is added to the playlist
- You call the function more times, which results in almost all numbers from range [1, 30] being used
- This increases the chance of the first condition being met
- Which makes possible that for many successive, recursive calls of
getNextTrack
the track already exists.
- Which may result in stack overflow.
Note that the numbers will be repeated most of the time, because you keep using a new random generator. The documentation of Random
constructor says:
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. This problem can be avoided by using a single Random object to generate all random numbers. You can also work around it by modifying the seed value returned by the system clock and then explicitly providing this new seed value to the Random(Int32) constructor. For more information, see the Random(Int32) constructor.
(emphasis mine)
The recursion necessary for a stack overflow to occur doesn't need to be conceptually infinite. It is sufficient for it to exceed the limit of the space on the stack. This is also explained in the documentation:
StackOverflowException is thrown for execution stack overflow errors, typically in case of a very deep or unbounded recursion.
(emphasis mine)