Fehler im System.Random-Konstruktor?
DasSystem.Threading.ConcurrentQueue.TryDequeue
Methode warf neulich eine Ausnahme, die mich völlig überraschte. Hier ist der Stack-Trace:
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()
Zuerst dachte ich, das Problem sei dasTryDequeueCore
nannte dieRandom
Konstruktor mit einem schlechten Wert. Weitere Untersuchungen zeigen jedoch, dassTryDequeueCore
ruft den Standardkonstruktor auf. Es sieht für mich so aus, als liege der Fehler in derRandom
Konstrukteur:
.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
Als Dokumentation für dieSystem.Environment.TickCount
Eigenschaft sagt:
Der Wert dieser Eigenschaft wird vom Systemzeitgeber abgeleitet und als 32-Bit-Ganzzahl mit Vorzeichen gespeichert. Wenn das System kontinuierlich ausgeführt wird, erhöht sich TickCount für ungefähr 24,9 Tage von Null auf Int32 .. ::. MaxValue, springt dann zu Int32 .. ::. MinValue, was eine negative Zahl ist, und erhöht sich dann während des Vorgangs wieder auf Null nächsten 24,9 Tage.
Also, wenn Sie die anrufenRandom
Konstruktor in diesem Zeitraum von einer Millisekunde (nachdem das System fürint.MaxValue
Millisekunden) wird diese Ausnahme ausgelöst.
Hat jemand eine Problemumgehung? Für meinen eigenen Code kann ich einen erstellenCreateRandom
Methode, die das bekommtTickCount
Wert und prüft es fürint.MinValue
. Aber was ist mit Code zu tun, über den ich keine Kontrolle habe?
Ich hoffe, das RTL-Team behebt dies in .NET 4.0.
Update 22.07.2009: Das BCL-Team hat auf den Fehler reagiert und mitgeteilt, dass er für die nächste Version behoben wurde.