As others have said, the problem is that new Random()
uses the current time to form the seed, and you're getting the same one lots of times.
Basically you want to create relatively few instances. As Random
isn't thread-safe, you need ThreadStatic
or ThreadLocal<T>
- the latter is new to .NET 4.0. Here's a sample StaticRandom
class (using .NET 4.0) which lets you use the Instance
property to get a valid instance for this thread. Note that on type initialization, a counter is set from the current time. This is then used for successive seeds.
using System;
using System.Threading;
public static class StaticRandom
{
private static int seed;
private static ThreadLocal<Random> threadLocal = new ThreadLocal<Random>
(() => new Random(Interlocked.Increment(ref seed)));
static StaticRandom()
{
seed = Environment.TickCount;
}
public static Random Instance { get { return threadLocal.Value; } }
}
Then you can just use StaticRandom.Instance
whenever you need an instance of Random
.
Now to get back to the original question, it's not entirely clear what your current extension method is doing. Why are you using DateTime.Today
at all? I suspect you want something like:
public static DateTimeOffset Random(this DateTimeOffset value, TimeSpan timeSpan)
{
double seconds = timeSpan.TotalSeconds * StaticRandom.Instance.NextDouble();
// Alternatively: return value.AddSeconds(-seconds);
TimeSpan span = TimeSpan.FromSeconds(seconds);
return value - span;
}
However, that will give you a completely random time - it's almost bound to be part way through a millisecond, for instance. Is that okay, or do you effectively want it to be an exact number of seconds (or minutes, or hours) based on the original timespan?