2

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

[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

4 回答 4

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,我也无法重复您的问题

于 2009-03-04T15:56:45.007 回答
1

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

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

于 2009-03-04T13:35:50.183 回答
1
1.0/0 

=> NaN正无穷大

在想0/0.0 :|

于 2009-03-04T14:08:09.123 回答
0

是否有可能很多堆栈跟踪正在被优化,并且你有一些代码在那里做一些没有显示的时间跨度的事情。

编辑:

在反射器中,我看到 Dispatcher.Invoke 调用 Timespan.FromMilliseconds 调用 Timespan.Interval。但是在堆栈跟踪中我们只看到 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

于 2009-03-04T14:29:39.350 回答