«Переполнение или переполнение в арифметической операции», специфичная для WPF - PullRequest
9 голосов
/ 09 марта 2010

Мое тестовое приложение WPF (очень простое, всего в одном окне) использует стороннюю управляемую dll (скажем, X.dll). Эта управляемая DLL использует некоторые неуправляемые DLL. Допустим, я пишу небольшое приложение wpf, которое просто ссылается на X.dll. И в конструкторе окна я получаю доступ к чему-то внутри X.dll (т.е. в некотором пространстве имен в X.dll). При этом я не улавливаю никаких исключений, и кажется, что все идет так, как ожидалось. Но по возвращении элемента управления в среду выполнения .NET я получаю исключение в обработчике DispatcherUnhandledException класса Application:

«Переполнение или переполнение в арифметической операции». System.ArithmeticException не было обработано Сообщение = "Переполнение или переполнение в арифметической операции."
Источник = "PresentationFramework"
StackTrace

System.Windows.Window.ValidateTopLeft(Double length)<br> System.Windows.Window.CoerceTop(DependencyObject d, Object value) System.Windows.DependencyObject.ProcessCoerceValue(DependencyProperty dp, PropertyMetadata metadata, EntryIndex& entryIndex, Int32& targetIndex, EffectiveValueEntry& newEntry, EffectiveValueEntry& oldEntry, Object& oldValue, Object baseValue, CoerceValueCallback coerceValueCallback, Boolean coerceWithDeferredReference, Boolean skipBaseValueChecks)<br> System.Windows.DependencyObject.UpdateEffectiveValue(EntryIndex entryIndex, DependencyProperty dp, PropertyMetadata metadata, EffectiveValueEntry oldEntry, EffectiveValueEntry& newEntry, Boolean coerceWithDeferredReference, OperationType operationType)<br> System.Windows.DependencyObject.CoerceValue(DependencyProperty dp) at System.Windows.Window.SetupInitialState(Double requestedTop, Double requestedLeft, Double requestedWidth, Double requestedHeight)<br> System.Windows.Window.CreateSourceWindowImpl() at System.Windows.Window.SafeCreateWindow() at System.Windows.Window.ShowHelper(Object booleanBox)<br> System.Windows.Threading.ExceptionWrapper.InternalRealCall(Delegate callback, Object args, Boolean isSingleParameter)<br> System.Windows.Threading.ExceptionWrapper.TryCatchWhen(Object source, Delegate callback, Object args, Boolean isSingleParameter, Delegate catchHandler)

Некоторые баллы:

  • Это происходит только в приложении WPF, а не в приложении winforms.
  • Это не попадает в ловушку. только в приложении DispatcherUnhandledException
  • Этого не происходит, если я получаю доступ к коду X.dll внутри события «Loaded» окна, это происходит только в конструкторе.

Кто-нибудь может угадать проблему?

Спасибо, Mishal

Ответы [ 3 ]

10 голосов
/ 01 ноября 2013

По ссылке @Mishhl исправление

public class FloatingPointReset
{
    [DllImport("msvcr110.dll", CallingConvention = CallingConvention.Cdecl)]
    public static extern int _fpreset();


    public static void Action()
    {
        // Reset the Floating Point (When called from External Application there was an Overflow exception)
        _fpreset();
    }
}

Это вызвано чем-то во включенной DLL, сбрасывающим FP в состояние, которое не совместимо с WPF / C # / Microsoft DLL. Delphi / CPPB делает это по умолчанию.

Так что либо в конструкторе окна, либо в конструкторе App () просто выполните

FloatingPointReset.Action();

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

[DllImport("msvcr110.dll", CallingConvention = CallingConvention.Cdecl)]

1012 *, например *

[DllImport("msvcr70.dll", CallingConvention = CallingConvention.Cdecl)]
5 голосов
/ 22 марта 2010

Я пока не уверен в основной причине, но решение здесь:
http://social.msdn.microsoft.com/forums/en-US/wpf/thread/a31f9c7a-0e15-4a09-a544-bec07f0f152c

Кажется, это популярная ошибка:)

спасибо, Mishal

1 голос
/ 10 февраля 2015

Если это может помочь, у меня была точно такая же проблема (как указано здесь и здесь ). Я привожу здесь одну из возможных причин этого.

Я использую ElementHost (c #, .net4.0, winform, VS2012) для отличного WPF UserControl. Все работало Отлично . В своем коде UserControl я использовал класс, который был написан из другой библиотеки DLL и использовался для хранения последовательности выполнения определенной задачи. Например (это близко к реальности):

public class SI_MyProgressionHelper
{
    public string gstr_OverallProgress_Description { get; set; }

    public int gint_OverallProgress_ActualValue { get; set; }
    public int gint_OverallProgress_MaximumValue { get; set; }
}

Затем я хотел «подключить» этот класс к моему WPF progressBar / textBox, чтобы сообщить о прогрессе. Однако (и это еще один разговор), WPF необходимо применить INotifyPropertyChanged к каждому отдельному свойству, которое вы хотите подключить к WPF (для автоматического обновления элементов управления в WPF). Это одна из самых уродливых вещей, которые я когда-либо видел, но это то, что есть (и я знаю, что должен что-то пропустить ..)

В любом случае, чтобы соответствовать WPF Механизм связывания между моим ProgressBar / textbox и моим классом SI_MyProgressionHelper, я изменил класс (который, повторяю, находится в другой DLL) так:

public class SI_MyProgressionHelper : INotifyPropertyChanged
{
    private string _gstr_OverallProgress_Description = "";
    public string gstr_OverallProgress_Description { get { return _gstr_OverallProgress_Description; } set { _gstr_OverallProgress_Description = value; RaisePropertyChanged("gstr_OverallProgress_Description"); } }   

    private int _gint_OverallProgress_ActualValue = 0;
    public int gint_OverallProgress_ActualValue { get { return _gint_OverallProgress_ActualValue; } set { _gint_OverallProgress_ActualValue = value; RaisePropertyChanged("gint_OverallProgress_ActualValue"); } }   

    private int _gint_OverallProgress_MaximumValue = 9999;
    public int gint_OverallProgress_MaximumValue { get { return _gint_OverallProgress_MaximumValue; } set { _gint_OverallProgress_MaximumValue = value; RaisePropertyChanged("gint_OverallProgress_MaximumValue"); } }   


    protected virtual void RaisePropertyChanged(string propName)
    {
        if (PropertyChanged != null)
            PropertyChanged(this, new PropertyChangedEventArgs(propName));
    }
    public event PropertyChangedEventHandler PropertyChanged;
}

БАМ! Ошибка возникает в любом случайном целочисленном свойстве любого элемента XMLElement (высоты, ширины и т. Д.) Моего UserContrl (в точности так, как указано здесь и в другой ссылке, указанной выше).

Применение приведенного здесь решения исправляет мою проблему: В моем методе Program.cs Main ():

[DllImport( "msvcr70.dll", CallingConvention = CallingConvention.Cdecl )]
public static extern int _fpreset();

, а затем, в моем UserControl.xaml.cs, в конструкторе:

public UserControl1()
{
    Program._fpreset(); 
    InitializeComponent();
} 

Кроме того, и именно поэтому я написал этот комментарий : удалив INotifyPropertyChanged для моего класса Helper (и других связанных с этим вещей), проблема исчезнет . (но мой WPF грустный, потому что мой код слишком короткий для него).

Надеюсь, что эта дополнительная информация может помочь кому-то, имеющему ту же проблему.

Кроме того, для всех моих французских коллег, вот французская ошибка:

В любом случае, если вы хотите продвинуться вперед Домашняя арифметика.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...