Bug no construtor System.Random?
oSystem.Threading.ConcurrentQueue.TryDequeue
método lançou uma exceção no outro dia que me pegou totalmente de surpresa. Aqui está o rastreamento de pilha:
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()
No começo eu pensei que o problema era queTryDequeueCore
Chamou oRandom
construtor com um valor ruim. Mas uma investigação mais aprofundada revela queTryDequeueCore
chama o construtor padrão. Parece-me que o erro está noRandom
construtor:
.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
Como a documentação para oSystem.Environment.TickCount
propriedade diz:
O valor dessa propriedade é derivado do cronômetro do sistema e é armazenado como um inteiro assinado de 32 bits. Conseqüentemente, se o sistema for executado continuamente, o TickCount aumentará de zero para Int32 .. ::. MaxValue por aproximadamente 24,9 dias e, em seguida, passará para Int32.. ::. MinValue, que é um número negativo. próximos 24,9 dias.
Então, se você ligar para oRandom
construtor durante esse período de um milissegundo (após o sistema ter sidoint.MaxValue
milissegundos), vai lançar essa exceção.
Alguém tem uma solução alternativa? Para o meu próprio código, posso fazer umaCreateRandom
método que recebe oTickCount
valor e verifica paraint.MinValue
. Mas o que fazer com o código sobre o qual não tenho controle?
Espero que a equipe de RTL corrija isso no .NET 4.0.
Atualização 2009/07/22: A equipe BCL respondeu ao bug e disse que ele foi resolvido para o próximo lançamento.