soren.enemaerke
soren.enemaerke

Reputation: 4830

TimeSpan.FromSeconds(-1.0) and double.NaN

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

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?

Upvotes: 3

Views: 3291

Answers (4)

drscroogemcduck
drscroogemcduck

Reputation:

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

Upvotes: 0

leppie
leppie

Reputation: 117250

1.0/0 

=> NaN Positive infinity

Was thinking of 0/0.0 :|

Upvotes: 1

sisve
sisve

Reputation: 19781

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

Upvotes: 1

Mehrdad Afshari
Mehrdad Afshari

Reputation: 422006

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.

Upvotes: 1

Related Questions