2009-07-18 25 views
20

Phương pháp System.Threading.ConcurrentQueue.TryDequeue đã ném một ngoại lệ vào một ngày khác khiến tôi hoàn toàn bất ngờ. Dưới đây là stack trace:Lỗi trong 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() 

Lúc đầu, tôi nghĩ vấn đề là TryDequeueCore gọi các nhà xây dựng Random với một giá trị xấu. Nhưng điều tra thêm cho thấy rằng TryDequeueCore gọi hàm tạo mặc định. Có vẻ với tôi như lỗi này là trong Random constructor:

.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 

Là tài liệu cho System.Environment.TickCount bất động sản cho biết:

Giá trị tài sản này có nguồn gốc từ hệ thống hẹn giờ và được lưu trữ dưới dạng số nguyên có dấu 32 bit. Do đó, nếu hệ thống chạy liên tục, TickCount sẽ tăng từ 0 lênInt32 .. ::. MaxValue cho khoảng 24,9 ngày, sau đó chuyển đến Int32 .. ::. MinValue, là số âm, sau đó tăng trở lại về 0 trong 24,9 ngày tiếp theo.

Vì vậy, nếu bạn gọi constructor Random trong khoảng thời một phần nghìn giây (sau khi hệ thống đã được lập cho int.MaxValue mili giây), nó sẽ ném ngoại lệ này.

Có ai có giải pháp thay thế không? Đối với mã của riêng tôi, tôi có thể tạo phương thức CreateRandom nhận giá trị TickCount và kiểm tra giá trị int.MinValue. Nhưng phải làm gì về mã mà tôi không kiểm soát được?

Tôi hy vọng nhóm RTL sẽ sửa lỗi này trong .NET 4.0.

Cập nhật 2009/07/22: Nhóm BCL đã trả lời lỗi và cho biết rằng nó đã được giải quyết cho bản phát hành tiếp theo.

+2

Tôi hy vọng bạn đã thực hiện báo cáo lỗi :) – n3rd

+2

Điều tra tốt, tuyệt vời. – GManNickG

+1

Lỗi được báo cáo tại Microsoft Connect. https://connect.microsoft.com/VisualStudio Lỗi # 475447. –

Trả lời

4

try/catch và thử lại một phần nghìn giây sau đó có vẻ chỉ là điều duy nhất bạn có thể làm cho đến khi lỗi này được khắc phục.

+0

Có lẽ. Nhưng lấy trường hợp của ConcurrentQueue.TryDequeue. Phương pháp đó không phải là ném ngoại lệ. Bây giờ tôi phải bọc tất cả các cuộc gọi đến TryDequeue trong một khối try/catch. Và những gì về mã mà tôi không biết sử dụng ngẫu nhiên? –

+0

Miễn là sâu trong thư viện hệ thống có lỗi gây ra ngoại lệ khi bạn không bao giờ bị loại trừ, bạn có thể làm gì khác với mã ngoài tầm kiểm soát của mình, mà bạn không có nguồn và MIGHT gọi lib hệ thống trong câu hỏi? Trừ khi bạn có thể chuyển sang ngăn xếp nguồn mở, nơi bạn có thể khắc phục lỗi khi tìm thấy chúng, bạn chắc chắn sẽ không thể tránh khỏi lòng thương xót của nhà cung cấp mã độc quyền. try/catch chỉ là về điều duy nhất bạn có thể làm, và nó chắc chắn không hoàn hảo, nhưng, còn gì nữa? –