TimeSpan.FromSeconds(-1.0) 和 double.NaN

发布于 2024-07-14 16:11:27 字数 1541 浏览 5 评论 0原文

我们正在构建一个 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?)并中断并检查堆栈/堆以验证值?

我们的应用程序数据量很大,有大量数据是异步获取的,还有大量数据绑定,但从我们能够获得的堆栈跟踪中,我们没有看到任何确凿的证据。

只是为了澄清这个问题:是否有人以前见过所描述的行为,认识到症状或对我们如何调试这种情况有意见?

想法、评论、想法、建议?

We are building a WPF app and are seeing some random and very strange behavior which seems to originate from within the BCL. We are catching an unhandled exception with the following 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)

Now, if we are to believe Reflector the calling method (Dispatcher.Invoke) calls

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

which throws an Argument exception because the argument being passed in returns true on double.IsNaN. This is clearly not making any sense and we find this very puzzling, to say the least.

We have been unable to reproduce this behavior in any smaller samples, so we are looking for ways to determine the cause of this (and other seemingly related TimeSpan exceptions which are also thrown) in our full app. We have a number of questions they we hope someone can help us with, as we have had no luck in googling for anything like this

  • Has anybody seen such behavior or recognize the symptoms
  • What causes these seemingly random behavior in basic math, are we somehow corrupting the stack or heap?
  • Can we somehow debug the IL in TimeSpan.Interval (WinDbg perhaps?) and break and inspect the stack/heap to verify the values?

Our application is quite data heavy, with lots of data being fetched async and lots of data binding, but we see no smoking gun pointing at any of this from the stack traces we have been able to obtain.

Just to clarify the question: Has anybody seen the described behavior before, recognizes the symptoms or has input as to how we can debug the situation?

Thoughts, comments, ideas, suggestions?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

勿忘初心 2024-07-21 16:11:27

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

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

I'm not sure I understand your question correctly but I don't think -1.0 is NaN.

EDIT (To solve the actual problem): You could download .NET Framework symbols and debug through them to see the actual value of the variable passed to TimeSpan.FromSeconds and whatever else that might be going on.

千笙结 2024-07-21 16:11:27

关于堆栈跟踪的快速说明,如果方法调用符合某些要求,则可以内联方法调用。 有关详细信息,请阅读 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

A quick note on the stack traces, method calls can be inlined if they match certain requirements. For more info, read http://blogs.msdn.com/ericgu/archive/2004/01/29/64717.aspx

The IL code for the Dispatcher.Invoke call:

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

My test code, C#:

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

Which becomes the following IL code:

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)

I can not repeat your problem, even when passing the exact same value to TimeSpan.FromMilliseconds

很酷不放纵 2024-07-21 16:11:27
1.0/0 

=> NaN 正无穷

正在考虑 0/0.0 :|

1.0/0 

=> NaN Positive infinity

Was thinking of 0/0.0 :|

恋竹姑娘 2024-07-21 16:11:27

是否有可能大量堆栈跟踪正在被优化,并且其中有一些代码正在执行未显示的时间跨度的操作。

编辑:

在反射器中,我看到 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

is it possible a lot of the stack trace is being optimized out and you have some code in there which is doing stuff with timespans which is not showing up.

EDIT:

in reflector i see Dispatcher.Invoke call Timespan.FromMilliseconds which calls Timespan.Interval. But in the stack trace we only see Dispatcher.Invoke and Timespan.Interval so Timespan.FromMilliseconds is being left out of the stacktrace. if we assume methods could be left out of the stacktrace then maybe there is a totally different path to Timespan.Interval. say:

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

if the control flow is Dispatcher.Invoker->Timepan.FromMilliseconds -> Timespan.Interval then i would start suspecting a JIT compilation bug or some kind of corruption from the native code that is running beforehand.

here is a page on how to see the code generated by the JIT:
http://blogs.msdn.com/vancem/archive/2006/02/20/535807.aspx

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文