Ошибка в конструкторе System.Random?
System.Threading.ConcurrentQueue.TryDequeue
Метод на днях бросил исключение, которое застало меня врасплох. Вот трассировка стека:
System.OverflowException: Negating the minimum value of a twos complement number is invalid.
at System.Math.AbsHelper(Int32 value)
at System.Random..ctor(Int32 Seed)
at System.Threading.Collections.ConcurrentQueue`1.TryDequeueCore(T& result)
at System.Threading.Collections.ConcurrentQueue`1.TryDequeue(T& result)
at MyProgram.ThreadProc() in c:\MyProgram\Main.cs:line 118
at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state)
at System.Threading.ThreadHelper.ThreadStart()
Сначала я подумал, что проблема в том, чтоTryDequeueCore
называетсяRandom
конструктор с плохим значением. Но дальнейшее расследование показывает, чтоTryDequeueCore
вызывает конструктор по умолчанию Мне кажется, что ошибка вRandom
конструктор:
.method public hidebysig specialname rtspecialname
instance void .ctor() cil managed
{
// Code size 12 (0xc)
.maxstack 8
IL_0000: ldarg.0
IL_0001: call int32 System.Environment::get_TickCount()
IL_0006: call instance void System.Random::.ctor(int32)
IL_000b: ret
} // end of method Random::.ctor
В качестве документации дляSystem.Environment.TickCount
собственность говорит:
The value of this property is derived from the system timer and is stored as a 32-bit signed integer. Consequently, if the system runs continuously, TickCount will increment from zero to Int32..::.MaxValue for approximately 24.9 days, then jump to Int32..::.MinValue, which is a negative number, then increment back to zero during the next 24.9 days.
Итак, если вы называетеRandom
конструктор в течение этого периода в одну миллисекунду (после того, как системаint.MaxValue
миллисекунды), это будет выбрасывать это исключение.
У кого-нибудь есть обходной путь? Для моего собственного кода я могу сделатьCreateRandom
метод, который получаетTickCount
значение и проверяет его наint.MinValue
, Но что делать с кодом, который я не могу контролировать?
Я надеюсь, что команда RTL исправит это в .NET 4.0.
Обновление 2009/07/22: Команда BCL ответила на ошибку и сказала, что она исправлена в следующем выпуске.