Il metodo System.Threading.ConcurrentQueue.TryDequeue
ha emesso un'eccezione l'altro giorno che mi ha colto di sorpresa. Ecco l'analisi dello stack:Bug in System.Random constructor?
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()
In un primo momento ho pensato che il problema era che TryDequeueCore
chiamato il Random
costruttore con un pessimo affare. Ma ulteriori indagini rivelano che TryDequeueCore
chiama il costruttore predefinito. Sembra a me come l'errore è nel Random
costruttore:
.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
quanto la documentazione per la proprietà System.Environment.TickCount
dice:
Il valore di questa proprietà è derivato dal timer di sistema e viene memorizzato come un numero intero con segno a 32 bit. Di conseguenza, se il sistema viene eseguito continuamente, TickCount incrementerà da zero a Int32 .. ::. MaxValue per circa 24,9 giorni, quindi passare a Int32 .. ::. MinValue, che è un numero negativo , quindi incrementare indietro a zero durante i prossimi 24,9 giorni.
Quindi, se si chiama il costruttore Random
durante quel periodo di un millisecondo (dopo che il sistema è stato per int.MaxValue
millisecondi), che sta per lanciare questa eccezione.
Qualcuno ha una soluzione alternativa? Per il mio codice personale, posso creare un metodo CreateRandom
che ottiene il valore TickCount
e lo controlla per int.MinValue
. Ma cosa fare del codice su cui non ho controllo?
Spero che il team RTL lo risolva in .NET 4.0.
Aggiornamento 2009/07/22: Il team BCL ha risposto al bug e ha affermato che è stato risolto per la prossima versione.
Spero tu abbia fatto un bug report :) – n3rd
Wow, bella indagine. – GManNickG
Bug segnalato in Microsoft Connect. https://connect.microsoft.com/VisualStudio Bug # 475447. –