Как уже говорили другие, проблема в том, что new Random()
использует текущее время для формирования начального числа, и вы получаете одно и то же много раз.
По сути, вы хотите создать относительно немного экземпляров. Поскольку Random
не является потокобезопасным, вам нужно ThreadStatic
или ThreadLocal<T>
- последний является новым для .NET 4.0. Вот пример класса StaticRandom
(с использованием .NET 4.0), который позволяет использовать свойство Instance
, чтобы получить действительный экземпляр для этого потока. Обратите внимание, что при инициализации типа счетчик устанавливается с текущего времени. Это тогда используется для последовательных семян.
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; } }
}
Тогда вы можете просто использовать StaticRandom.Instance
всякий раз, когда вам нужен экземпляр Random
.
Теперь, чтобы вернуться к исходному вопросу, не совсем понятно, что делает ваш текущий метод расширения. Почему вы вообще используете DateTime.Today
? Я подозреваю, что вы хотите что-то вроде:
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;
}
Однако, это даст вам полностью случайное время - например, оно почти наверняка пройдет часть пути через миллисекунду. Это нормально, или вы действительно хотите, чтобы это было точное количество секунд (или минут, или часов) в зависимости от исходного времени?