TimeSpan.FromSeconds(-1.0)和double.NaN

时间:2009-03-04 13:32:56

标签: .net debugging timespan

我们正在构建一个WPF应用程序,并且看到一些随机且非常奇怪的行为,这些行为似乎来自BCL内部。我们正在使用以下stacktrace捕获未处理的异常:

[ArgumentException], 
"TimeSpan does not accept floating point Not-a-Number values."
   at System.TimeSpan.Interval(Double value, Int32 scale)
   at System.Windows.Threading.Dispatcher.Invoke(DispatcherPriority priority, Delegate method, Object arg)
   at MS.Win32.HwndSubclass.SubclassWndProc(IntPtr hwnd, Int32 msg, IntPtr wParam, IntPtr lParam)
   at MS.Win32.UnsafeNativeMethods.DispatchMessage(MSG& msg)
   at System.Windows.Threading.Dispatcher.PushFrameImpl(DispatcherFrame frame)
   at System.Windows.Threading.Dispatcher.PushFrame(DispatcherFrame frame)
   at System.Windows.Threading.Dispatcher.Run()
   at System.Windows.Application.RunDispatcher(Object ignore)
   at System.Windows.Application.RunInternal(Window window)
   at System.Windows.Application.Run(Window window)

现在,如果我们要相信Reflector调用方法(Dispatcher.Invoke)调用

...,TimeSpan.FromSeconds(-1.0),...

抛出一个Argument异常,因为传入的参数在double.IsNaN上返回true。这显然没有任何意义,我们发现这非常令人费解,至少可以说。

我们无法在任何较小的样本中重现此行为,因此我们正在寻找在我们的完整应用程序中确定原因(以及其他看似相关的TimeSpan异常也会被抛出)的方法。我们有一些问题,我们希望有人可以帮助我们,因为我们没有运气搜索这样的事情

  • 是否有人见过这种行为或认出症状
  • 在基本数学中导致这些看似随机的行为的原因是,我们是否会以某种方式破坏堆栈或堆?
  • 我们可以以某种方式调试TimeSpan.Interval中的IL(也许是WinDbg?)并中断并检查堆栈/堆以验证值?

我们的应用程序数据非常庞大,大量数据被异步获取并且有大量数据绑定,但是我们看到没有冒烟的枪指向我们能够获得的堆栈跟踪中的任何一个。

只是为了澄清这个问题:有没有人看过之前描述过的行为,认识到症状,或者对我们如何调试情况有所了解?

思考,评论,想法,建议?

4 个答案:

答案 0 :(得分:1)

我不确定我是否理解你的问题,但我认为-1.0不是NaN。

编辑(解决实际问题):您可以下载.NET Framework符号并通过它们进行调试,以查看传递给TimeSpan.FromSeconds的变量的实际值以及可能发生的任何其他内容。

答案 1 :(得分:1)

1.0/0 

=> NaN 正无穷

想到0/0.0:|

答案 2 :(得分:1)

关于堆栈跟踪的快速说明,如果方法调用符合某些要求,则可以内联它们。有关详细信息,请阅读http://blogs.msdn.com/ericgu/archive/2004/01/29/64717.aspx

Dispatcher.Invoke调用的IL代码:

L_0002: ldc.r8 -1
L_000b: call valuetype [mscorlib]System.TimeSpan [mscorlib]System.TimeSpan::FromMilliseconds(float64)

我的测试代码,C#:

double d = -1.0;
TimeSpan t = TimeSpan.FromMilliseconds(d);

哪个成为以下IL代码:

L_0001: ldc.r8 -1
L_000a: stloc.0 
L_000b: ldloc.0 
L_000c: call valuetype [mscorlib]System.TimeSpan [mscorlib]System.TimeSpan::FromMilliseconds(float64)

我无法重复您的问题,即使将完全相同的值传递给TimeSpan.FromMilliseconds

答案 3 :(得分:0)

是否有可能很多堆栈跟踪正在被优化,并且你有一些代码在那里做了没有出现的timepans的东西。

编辑:

反射器中的

我看到调用Timespan.Interval的Dispatcher.Invoke调用Timespan.FromMilliseconds。但是在堆栈跟踪中我们只看到Dispatcher.Invoke和Timespan.Interval,因此Timespan.FromMilliseconds被排除在堆栈跟踪之外。如果我们假设方法可以被排除在堆栈跟踪之外,那么可能存在与Timespan.Interval完全不同的路径。说:

Dispatcher.Invoke
Dispatcher.InvokeImpl
Dispatcher.BeginInvoke
- Call into your code or somewhere else in BCL -
Timespan.Interval

如果控制流是Dispatcher.Invoker-> Timepan.FromMilliseconds - > Timespan.Interval然后我会开始怀疑JIT编译错误或事先运行的本机代码的某种损坏。

这是一个关于如何查看JIT生成的代码的页面: http://blogs.msdn.com/vancem/archive/2006/02/20/535807.aspx