【问题标题】:WPF SetParent throwing an ArithmeticExceptionWPF SetParent 引发 ArithmeticException
【发布时间】:2018-07-19 03:03:03
【问题描述】:

我一直在为应用程序开发一个使用 C# 和 WPF 的插件。

它一直运行良好,直到在 Win7 机器上启动。症状是 Microsoft .NET Framwork 的“未处理异常”对话框在启动时弹出 System.ArithmeticException(算术运算中的溢出或下溢),并给出指向 System.Windows.Controls.Primitives.Track.ComputeScrollBarLengths (...) 和更深层次的堆栈跟踪.

所以,我开始调试应用程序:它显示在调用 user32.dll 中的 setParent 时抛出了 System.ArithmeticException。这是在应用程序调用显示插件 UI 时完成的。

public bool ShowUI(int Parent)
{
userControl = new MyUserControl(); // Extends System.Windows.Forms.UserControl
SetParent(userControl.Handle, new IntPtr(Parent)); // <- exception thrown here
...
}

什么可能导致这个问题?

【问题讨论】:

  • 这个异常总是由非托管代码更改浮点处理器控制寄存器引起的。 WPF 有一个严格的要求,那就是永远不会发生这种情况,浮点异常需要保持禁用状态。使用this post 中的调试提示追踪它。
  • 谢谢。显然它与它有关,因为从加载项的引导程序中的 msvcrt.dll 调用 _fpreset() 现在似乎可以解决这个问题。不过,它需要进一步测试......

标签: c# wpf winapi user32 setparent


【解决方案1】:

我在这里添加解决方案,以防有人发现它有用。

如 Hans Passant 的评论中所述,非托管代码中的某些内容(但仅在 64 位版本中)导致浮点操作引发异常,从而导致此错误。解决方案类似于此答案:https://stackoverflow.com/a/19722292/8063451

在我的插件初始化时添加_fpreset() 函数调用解决了这个问题。

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

    public static void Run()
    {
       // Other code
        _fpreset(); // Reinitialises the floating-point package
    }

【讨论】:

    猜你喜欢
    • 2011-02-14
    • 2012-12-17
    • 2015-10-28
    • 2023-03-22
    • 2015-07-26
    • 1970-01-01
    • 2011-01-26
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多