views:

80

answers:

2

I'm experiencing a problem with my random number generator in a class library returning the same value repeatedly. It returns the same value b/c it is repeatedly initialized with the default constructor - for example:

public static T GetRandomValue<T>(T[] array)
{            
    int ndx = new Random().Next(array.Length);
    return array[ndx];            
}

This is called repeatedly from another method before the system clock can change, so it is initialized with the same random seed, giving the same value. (see SO article for apparently malfunctioning random number generator) It is used to select a random format string for some text generation algorithms. Because it is called in rapid sequence every time my different bits of text generates with a homogeneous formatting string, which is undesirable for the application.

It is typically called from an asp.net webpage, and I'm wondering what the best approach is to produce a random sequence, without creating performance issues for the pages that call the method repeatedly.

A web page calls the library method, which calls the random number. I am wondering if i can use this approach for a static number generator instead. Are there performance issues associated with calling a static method like this from a webpage?

public class Utility
{
    public static Random random = new Random();
    public static T GetRandomValue<T>(T[] array)
    {            
        int ndx = random.Next(array.Length);
        return array[ndx];            
    }
}

A lock on "random" and "ndx" may be needed too. Is there a better practice in general for handling this type of seeding in a class library?

A: 

The second approach is way better. The first does not guarantee a random string; you probably get arrays filled with the same value indeed. Even more so, I think the second approach is better regarding performance, because you only create one Random generator for the entire application.

I even think it will only be re-instantiated when the worker process recycles (can anyone verify this?).

Cloud
+1  A: 

I usually do something like the following.

public class Utility
{
    public static readonly Random MyRandomGenerator = new Random();

    static Utility()
    {
    }
}

Then just call Utility.MyRandomGenerator as if it were a regular {get;} property.

EDIT: I almost always include a static constructor when I'm doing something like this because of the nuttiness of the beforefieldinit flag. See this other post.

Repo Man