views:

486

answers:

4

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?

+1  A: 

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.

Mehrdad Afshari
Well this is exactly why we are puzzled! If Reflector is correct, then TimeSpan.FromSeconds(-1.0) should NOT throw an exception. But that is the situation on our machines and we are kind of desperate to figure out what is going on...
soren.enemaerke
We've tried that, but the VS debugging says that everything is optimized away, so we can't see the state/value of the variables or arguments...perhaps we're doing something wrong or need a tip for inspecting the arguments and variables
soren.enemaerke
+1  A: 
1.0/0

=> NaN Positive infinity

Was thinking of 0/0.0 :|

leppie
I see the confusion with the title mentioning 1...however, I hoped it was clear from the question that it is not our code that calls the TimeSpan.FromSeconds() method, it's some internal BCL call. We still get the argument exception from what looks to us(Reflector) to be a completely valid call...
soren.enemaerke
Ok, I'm off target here, but will look for answer still :)
leppie
A: 
Can't really see that happening for this particular stacktrace as it is entirely BCL code and it is quite clear that the exception is thrown from the internal method TimeSpan.Interval (exception message matches etc.)...but I may be mistaken, so please elaborate if you can
soren.enemaerke
Okay, I see what you mean, thanks for the clarification. I suspect that this is not the case, it's definitely not calling our code (if we can trust the debugger to break on exceptions) and I struggle to come up with a scenario where the invoker is something else when looking into Reflector.
soren.enemaerke
+1  A: 

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

Simon Svensson