System.Random构造函数中是否存在Bug?

20

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将从零递增到大约24.9天的Int32..::.MaxValue,然后跳到Int32..::.MinValue,这是一个负数,然后在接下来的24.9天内递增回到零。

因此,在该一毫秒时间段内(系统启动了int.MaxValue毫秒后),如果调用Random构造函数,它将抛出此异常。

有人有解决方法吗?对于我的代码,我可以创建一个CreateRandom方法获取TickCount值并检查它是否为int.MinValue。但对于我无法控制的代码怎么办?

我希望RTL团队在.NET 4.0中修复这个问题。

更新2009/07/22:BCL团队回应了该BUG并表示已经在下一个版本中解决了这个问题。


2
希望你已经提交了一个错误报告 :) - n3rd
2
哇,调查得真不错。 - GManNickG
1
在Microsoft Connect上报告了一个错误。 https://connect.microsoft.com/VisualStudio 错误编号#475447。 - Jim Mischel
实际上,我的错误报告是#475446。有人将其报告为475447。 - Jim Mischel
1个回答

4
尝试使用try/catch语句并稍后重试一毫秒似乎是目前唯一可做的事情,直到这个错误得到修复。

也许吧。但以ConcurrentQueue.TryDequeue为例,该方法根本不应抛出异常。现在我必须将所有对TryDequeue的调用都包装在try/catch块中。那么对于我不知道使用Random的代码呢? - Jim Mischel
只要在系统库的深处存在一个错误,会导致在不应该抛出异常的情况下抛出异常,对于你无法控制、没有源代码的其他代码,还能做什么呢?除非你可以切换到开源堆栈,在发现错误后进行修复,否则你不可避免地受制于专有代码供应商。try/catch几乎是唯一你能做的事情,虽然它并不完美,但又能怎么办呢? - Alex Martelli

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接