Подтвердить что ты не робот

Ошибка в конструкторе 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:

Значение этого свойства получается от системного таймера и сохраняется как 32-битное целое число со знаком. Вследствие этого, если система работает непрерывно, TickCount будет увеличиваться с нуля до Int32..::. MaxValue для приблизительно 24.9 дней, затем перейдите к Int32..::. MinValue, который является отрицательное число, затем увеличивать назад к нулю в течение следующих 24.9 дней.

Итак, если вы вызываете конструктор Random в течение этого одного миллисекундного периода (после того, как система была в состоянии int.MaxValue миллисекунды), она собирается выбросить это исключение.

Есть ли у кого-нибудь обход? Для моего собственного кода я могу сделать метод CreateRandom, который получает значение TickCount и проверяет его на int.MinValue. Но что делать с кодом, который я не контролирую?

Я надеюсь, что команда RTL исправляет это в .NET 4.0.

Обновление 2009/07/22: Команда BCL ответила на ошибку и сказала, что она была разрешена для следующего выпуска.

4b9b3361

Ответ 1

try/catch и повторите попытку через миллисекунду, похоже, просто единственное, что вы можете сделать, пока эта ошибка не будет исправлена.