Ответ 1
try
/catch
и повторите попытку через миллисекунду, похоже, просто единственное, что вы можете сделать, пока эта ошибка не будет исправлена.
Метод 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 ответила на ошибку и сказала, что она была разрешена для следующего выпуска.
try
/catch
и повторите попытку через миллисекунду, похоже, просто единственное, что вы можете сделать, пока эта ошибка не будет исправлена.