Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Random object not disposing in C#

Tags:

c#

xna

I am working on a smooth terrain generation algorithm in C# and using XNA to display the data.

I am making it so it creates a new point halfway between each point per iteration, at a random height between the two. This works OK, and I have set it so that on the second iteration it chooses a random point like in slide two, rather than trying to make a new point between points that are on the same axis.

What is happening is that the loop is using the same random value from the previous iteration: http://i.stack.imgur.com/UmWr7.png

This is not ideal obviously, as it is not a proper random generation.

If I use a Thread.Sleep(20) after each point generation it works correctly: http://i.stack.imgur.com/KziOg.png

I don't want to have to use the Sleep workaround if possible as it is very slow, and I would like to use this in real-time. I'm pretty sure this has something to do with the C# garbage collector.

Here is my Get Point Code

Random r = new Random();
int x = (p1.X + p2.X) / 2;
int y;
if (!initial)
       y = r.Next(Math.Min(p1.Y, p2.Y), Math.Max(p1.Y, p2.Y));
else
       y = r.Next(Math.Min(p1.Y, p2.Y) - Game1.screenHeight / 2, Math.Max(p1.Y, p2.Y) + Game1.screenHeight / 2);
return new Point(x, y);

Is the garbage collection a part of the issue?

Any suggestions or solutions on solving this??

like image 531
coffeesaga Avatar asked Oct 29 '11 22:10

coffeesaga


2 Answers

Probably you are creating a new Random object in a loop.

for (/* ... */) {
    int x = new Random().Next(); // Don't do this!
    // ...
}

Try to create only one instance of Random at program startup, then re-use it. If you have multiple threads, then you could use one random object per thread.

like image 99
Mark Byers Avatar answered Oct 29 '22 13:10

Mark Byers


It sounds like you're probably creating a new instance of Random on each iteration1. That will take its seed from the current time - so without a sleep, you end up with the same value repeatedly; with a sleep you end up getting a different seed.

The answer is to reuse one Random instance throughout your program - but taking note of the fact that Random isn't thread-safe. If all your work is being done in the UI thread, you'll be fine - but otherwise you may want to use one of the approaches I've given in my article about Random (which talks about this problem more).


1 And yes, now that you've posted the code that is indeed the case.

like image 32
Jon Skeet Avatar answered Oct 29 '22 14:10

Jon Skeet