System.Random构造函数中的错误?
System.Threading.ConcurrentQueue.TryDequeue
方法在前几天引发了一个exception,让我完全惊讶。 这是堆栈跟踪:
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天。
因此,如果在一毫秒的时间内(在系统已经达到int.MaxValue
毫秒之后)调用Random
构造函数,它将抛出此exception。
有人有解决方法吗? 对于我自己的代码,我可以创建一个获取int.MinValue
值的int.MinValue
方法并检查它是否为int.MinValue
。 但是如何处理我无法控制的代码呢?
我希望RTL团队在.NET 4.0中修复此问题。
更新2009/07/22:BCL团队回复了该漏洞并表示已经解决了下一个版本。
try
/ catch
并在一毫秒后重试似乎只是你可以做的唯一事情,直到这个bug得到修复。