gpt4 book ai didi

c# - 来自 System.Windows.Forms 的 AccessViolationException,在 WPF 中使用 WinFormsHost

转载 作者:行者123 更新时间:2023-11-30 18:06:14 26 4
gpt4 key购买 nike

我在开发 WPF/WinForms 互操作应用程序时遇到了一个棘手的问题。我已经尝试解决这个问题三天了,但我无法取得任何进展。我怀疑我能否提供足够的信息来获得解决方案,但我正在寻找可以解释这里到底发生了什么的人?

我使用的组件是 AxMapControl (ESRI ArcGIS Engine 9.3.1 SP2),据我所知,它是 COM 包装的 native 代码,作为 WinForms 控件公开。该组件使用 WPF WinFormsHost 代理嵌入到我们的 WPF (.NET 3.5) 客户端软件中。

应用程序会定期因 AccessViolationException 严重崩溃。这总是对用户鼠标单击 map 控件的 react 发生,但似乎没有任何关于特定输入的押韵或原因。堆栈跟踪始终相同:

System.AccessViolationException: Attempted to read or write protected memory. This is often an indication that other memory is corrupt. at System.Windows.Forms.UnsafeNativeMethods.CallWindowProc(IntPtr wndProc, IntPtr hWnd, Int32 msg, IntPtr wParam, IntPtr lParam) at System.Windows.Forms.NativeWindow.DefWndProc(Message& m) at System.Windows.Forms.Control.DefWndProc(Message& m) at System.Windows.Forms.AxHost.WndProc(Message& m) at System.Windows.Forms.Control.ControlNativeWindow.OnMessage(Message& m) at System.Windows.Forms.Control.ControlNativeWindow.WndProc(Message& m) at System.Windows.Forms.NativeWindow.Callback(IntPtr hWnd, Int32 msg, IntPtr wparam, IntPtr lparam)

因为异常似乎是在我的代码启动的任何调用堆栈之外抛出的,所以我不知道如何捕获异常并以编程方式处理它。

此问题发生在 Debug模式以及发布版本中。然而,并非所有计算机上都会出现这种情况,但我已经能够在 Windows 7 和 XP 以及 .NET Framework 3.5 和 4.0 上重现此问题。

检查崩溃时进程在做什么,异常情况似乎是在 GAC 部署的 DLL 上似乎有多个 CreateFileMapping 操作失败,结果 文件仅由读者锁定

ProcMon screenshot

此 View 已被过滤以仅显示该类型的结果,但似乎每个 DLL 恰好发生两次。这意味着什么吗?

现在,很明显我对正在发生的事情以及如何解决这个问题一无所知。如果您有线索,能否友好地向我解释一下我正在处理的是哪种类型的问题?

知道如何调试这个问题吗?

最佳答案

我使用的是不同于 ESRI 的 map 控件,但我的设置非常相似:本地 map 代码包装在 COM 中,包装在 Windows 窗体控件中,然后通过 WindowsFormsHost 引入 WPF 应用程序。几周前,当我点击我的 map 时,我得到了完全相同的 System.AccessViolationException,几乎没有帮助调试的选项。

我的问题的罪魁祸首:WPF 中底层控件的初始化并没有像我想象的那样发生——WPF 推迟某些初始化,直到 View 完全需要/在屏幕上可见(我假设减少窗口/控件加载时间)。在 WPF 中,我将底层 map 控件的所有初始化代码放入构造函数和 (WPF) UserControl.Loaded 事件处理程序中。问题是,WPF 在屏幕上真正可见之前调用构造函数并引发 Loaded 事件。所以我的底层 map 控件被初始化为 0 高度、0 宽度的表面大小,这是合法但不正确的。当我单击 map 时,我正在调用底层 map 控件以将我的鼠标单击 (x, y) 转换为经纬度,这引发了 AccessViolationException。

我的解决方法是在每次引发 UserControl.Resize 事件时使用新的表面大小重新初始化底层 map 控件,这似乎可靠地发生在 map 以适当大小完全绘制之前,并保留 bool mapIsInitialized 字段在我的 WPF 控件中,在将 map 初始化为非零表面大小、设置适当的投影并首次完全绘制 map 之前,该控件一直为 false。我的函数(例如,将屏幕点转换为经纬度)访问底层 map 控件现在什么都不做,除非 mapIsInitialized。

因此,您可能有也可能没有类似的问题,但我会尝试跟踪初始化代码并查看传递给底层 map 控件的参数值,看看它们是否有意义,以及是否初始化如您所愿,在正确的时间使用正确的值。

祝你好运!

关于c# - 来自 System.Windows.Forms 的 AccessViolationException,在 WPF 中使用 WinFormsHost,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5017967/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com