2009-03-04 3 views
2

Мы создаем приложение WPF и видим какое-то случайное и очень странное поведение, которое, как представляется, происходит изнутри BCL. Мы ловим необработанное исключение со следующим StackTrace:TimeSpan.FromSeconds (-1.0) и double.NaN

[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) 

Теперь, если мы должны верить Отражатель метод вызова (Dispatcher.Invoke) называет

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

, который генерирует исключение Аргумент, поскольку аргумент передается в возвращает true на double.IsNaN. Это явно не имеет никакого смысла, и мы находим это очень озадачивающим, мягко говоря.

Мы не смогли воспроизвести это поведение в любых более мелких образцах, поэтому мы ищем способы определить причину этого (и другие, казалось бы, связанные с ним исключения TimeSpan, которые также выбрасываются) в нашем полном приложении. У нас есть ряд вопросов, которые они, мы надеемся, кто-то может помочь нам, так как мы не имели никакой удачи в прибегая к помощи ни за что, как этот

  • ли кто-нибудь видел такое поведение или распознать симптомы
  • Что вызывает эти, казалось бы, случайные поведение в базовой математике, мы как-то развращаем стек или кучу?
  • Можем ли мы как-то отладить IL в TimeSpan.Interval (возможно, WinDbg?), И разбить и проверить стек/кучу, чтобы проверить значения?

Наше приложение довольно тяжелое для данных, с большим количеством данных, получаемых с помощью асинхронной передачи данных и большого количества привязки данных, но мы не видим курящего пистолета, указывающего на любой из этих трасс, которые мы смогли получить.

Просто для выяснения вопроса: кто-либо видел описанное поведение раньше, распознает симптомы или имеет информацию о том, как мы можем отлаживать ситуацию?

Мысли, комментарии, идеи, предложения?

+0

Я бы попробовал сообщить об этом Microsoft. Похоже на довольно странное поведение. – leppie

+0

У нас есть точно такой же симптом, такой же stacktrace. Но я не знаю, где искать. Наша программа тоже большая, и все вызовы TimeSpan.From ... выполняются с помощью int-s, который не может содержать NaN. –

ответ

1

Я не уверен, что правильно понял ваш вопрос, но я не думаю, что -1.0 является NaN.

EDIT (Чтобы решить настоящую проблему): вы можете загрузить символы .NET Framework и отладить их, чтобы увидеть фактическое значение переменной, переданной в TimeSpan.FromSeconds, и все остальное, что может произойти.

+0

Ну, именно поэтому мы озадачены! Если Reflector is correct, то TimeSpan.FromSeconds (-1.0) НЕ должен вызывать исключение. Но такова ситуация на наших машинах, и мы отчаянно пытаемся понять, что происходит ... –

+0

Мы пробовали это, но отладка VS говорит, что все оптимизировано, поэтому мы не можем видеть состояние/значение переменных или аргументов ... возможно, мы делаем что-то неправильно или нуждаемся в подсказке для проверки аргументов и переменных –

1
1.0/0 

=> NaN Положительная бесконечность

Думал 0/0.0: |

+0

Я вижу путаницу с названием, упоминающим 1 ... однако, я надеялся, что это ясно из вопроса что это не наш код, который вызывает метод TimeSpan.FromSeconds(), это некоторый внутренний вызов BCL. Мы по-прежнему получаем исключение аргумента из того, что выглядит для нас (Reflector), чтобы быть полностью действующим вызовом ... –

+0

Хорошо, я ушел от цели, но буду искать ответ еще :) – leppie

0

Возможно ли, что большая часть трассировки стека оптимизирована, и у вас есть код, который делает вещи с временными рамками, которые не отображаются.

EDIT:

отражатель я вижу Dispatcher.Invoke Timespan.FromMilliseconds вызова, который называет Timespan.Interval. Но в трассировке стека мы видим только Dispatcher.Invoke и Timespan.Interval, поэтому Timespan.FromMilliseconds исключается из stacktrace. если мы предположим, что методы могут быть исключены из stacktrace, то, возможно, существует совершенно другой путь к 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

+0

Не могу видеть, что это происходит эта конкретная stacktrace, поскольку это полностью код BCL, и совершенно ясно, что исключение выбрано из внутреннего метода TimeSpan.Interval (сообщение об ошибке совпадает и т. д.) ... но я могу ошибаться, поэтому, пожалуйста, уточните, можете ли вы –

+0

Хорошо , Я понимаю, что вы имеете в виду, спасибо за разъяснение. Я подозреваю, что это не так, это определенно не вызывает наш код (если мы можем доверять отладчику, чтобы ломать исключения), и я изо всех сил пытаюсь придумать сценарий, когда invoker - это что-то другое, когда вы смотрите в Reflector. –

1

Быстрое примечание на трассировки стека, вызовы методов могут быть встраиваемыми, если они соответствуют определенным требованиям. Для получения дополнительной информации, читайте http://blogs.msdn.com/ericgu/archive/2004/01/29/64717.aspx

Код IL для вызова Dispatcher.Invoke:

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.From Миллисекунды

Смежные вопросы