2010-03-09 48 views
8

我的WPF测试应用程序(非常简单,只有一个窗口)正在使用第三方受管dll(如X.dll)。这个托管的DLL使用一些非托管的DLL。 所以我们可以说我写了一个小的wpf应用程序,它只是引用了X.dll。在窗口的构造函数中,我可以访问X.dll中的某些东西(即在X.dll中的某些命名空间中)。在这样做我不会捕捉任何异常,它似乎像事情正在按预期进行。但在返回控制到.NET运行时,我得到了应用程序类的“DispatcherUnhandledException”处理异常:“在算术运算溢出或下溢”“算术运算中溢出或下溢”WPF特定问题

System.ArithmeticException了未处理 消息 =“溢出或在算术运算中下溢。“
来源 = “PresentationFramework”
堆栈跟踪

System.Windows.Window.ValidateTopLeft(Double length)
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)
System.Windows.DependencyObject.UpdateEffectiveValue(EntryIndex entryIndex, DependencyProperty dp, PropertyMetadata metadata, EffectiveValueEntry oldEntry, EffectiveValueEntry& newEntry, Boolean coerceWithDeferredReference, OperationType operationType)
System.Windows.DependencyObject.CoerceValue(DependencyProperty dp) at System.Windows.Window.SetupInitialState(Double requestedTop, Double requestedLeft, Double requestedWidth, Double requestedHeight)
System.Windows.Window.CreateSourceWindowImpl() at System.Windows.Window.SafeCreateWindow() at System.Windows.Window.ShowHelper(Object booleanBox)
System.Windows.Threading.ExceptionWrapper.InternalRealCall(Delegate callback, Object args, Boolean isSingleParameter)
System.Windows.Threading.ExceptionWrapper.TryCatchWhen(Object source, Delegate callback, Object args, Boolean isSingleParameter, Delegate catchHandler)

几点:

  • 这只发生在WPF应用程序,而不是在WinForms应用程序。
  • 这不会被抓住试试看。只在应用程序的DispatcherUnhandledException
  • 这不会发生,如果我访问窗口的'Loaded'事件中的X.dll的代码,只发生在构造函数。

任何人都可以猜出问题吗?

感谢, 米沙勒

+0

当你说“访问”,你的意思是你传递的值作为参数的东西,对不对?你通过了什么? – Jay 2010-03-09 18:15:22

+0

如果我访问/读取整数XNameSpace.AStaticClass.StatInt(其中的XNamespace里面X.dll命名空间),并将其存储在另一个整数,我看到这一点。此外,我看到如果我把这个陈述放在try catch中,那么它就不会被捕获。它只会在System.Window.Application的DispatcherUnhandledException处理程序中被捕获......这真的很奇怪。 – mishal153 2010-03-11 15:09:42

回答

5

我不知道的根本原因,但还没有解决的办法是在这里:
http://social.msdn.microsoft.com/forums/en-US/wpf/thread/a31f9c7a-0e15-4a09-a544-bec07f0f152c

似乎是一个流行的错误:)

感谢, 米沙勒

+0

仅仅为了他人,链接中的建议解决方案更多地符合解决方法。这个问题本身似乎是WPF中的一个错误,尽管我不确定这个问题是否存在连接问题。 – jpierson 2014-05-01 01:52:35

+0

https://connect.microsoft.com/VisualStudio/feedback/details/382052/cryptic-arithmeticexception-in-system-double-equals-during-wpf-layout – jpierson 2014-05-01 01:58:55

10

继@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不兼容的状态。德尔福/ CPPB默认这样做。

所以无论是在窗口构造函数或应用程序()构造函数只是做

FloatingPointReset.Action(); 

您可能需要更改以下引用msvcr的###任何版本。DLL

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

例如

[DllImport("msvcr70.dll", CallingConvention = CallingConvention.Cdecl)] 
+0

我的建议是调用_fpreset不仅在构造函数,但与前在外部函数调用之后。从第三方COM对象库调用函数时出现此问题。 – Denis 2015-12-11 04:37:25

+0

对我来说,我通过遵循我正在使用的外部库来解决它,并且知道哪个msvcrXX。(它是msvcr100.dll),然后我调用** FloatingPointReset.Action(); **在调用** base.OnRender(drawingContext); **在我的UserControl之前。 – Dabbas 2017-04-11 17:13:00

0

如果它可以帮助,我有相同问题(这里说明和 here)。我在这里带来这个可能的原因之一。

我使用了一个伟大的WPF用户控件一个ElementHost的(C#,.net4.0,WinForm的,VS2012)。 一切正常大。在我的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进度/ textBox中,因为它去汇报进展。然而(这是另一次对话),WPF需要将INotifyPropertyChanged应用于要插入WPF的每个属性(以自动更新WPF中的控件)。这是我见过的最丑陋的事情之一,但它是它是什么(我知道我必须错过的东西..)

无论如何,遵守我的ProgressBar /文本框和我的SI_MyProgressionHelper类的WPF绑定mecanism,我已经修改了这个类(我重复,在另一个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; 
} 

BAM!我UserContrl任何的XMLElement(高度,宽度等)的任何随机整数属性时发生错误(正是因为这里所说和其他参考我在上面说明)。

应用带到这里并纠正我的问题的解决方案: 在我的Program.cs的Main()方法:

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

,然后在我的UserControl.xaml.cs,在构造函数中:

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

此外,这就是为什么我写的评论的原因:通过对我的Helper类取出INotifyPropertyChanged的(和其他的东西有关),问题消失。 (但是我的WPF很伤心,因为我的代码对他来说太短了)。

希望这其它附加信息,可以帮助找人同样的问题。

而且,我所有的法国同事,这里是遇到了法国的错误:

伊尔为y的欧盟未dépassement德capacitépositif欧négatif丹斯 L'操作arithmétique。

相关问题