3

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

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

应用程序会定期以AccessViolationException. 这总是在用户在地图控件上单击鼠标时发生,但似乎没有任何特定输入的押韵或原因。堆栈跟踪始终相同:

System.AccessViolationException:试图读取或写入受保护的内存。这通常表明其他内存已损坏。在 System.Windows.Forms.UnsafeNativeMethods.CallWindowProc(IntPtr wndProc, IntPtr hWnd, Int32 msg, IntPtr wParam, IntPtr lParam) 在 System.Windows.Forms.NativeWindow.DefWndProc(Message& m) 在 System.Windows.Forms.Control.DefWndProc (Message& m) 在 System.Windows.Forms.AxHost.WndProc(Message& m) 在 System.Windows.Forms.Control.ControlNativeWindow.OnMessage(Message& m) 在 System.Windows.Forms.Control.ControlNativeWindow.WndProc(Message& m)在 System.Windows.Forms.NativeWindow.Callback(IntPtr hWnd,Int32 msg,IntPtr wparam,IntPtr lparam)

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

此问题发生在调试模式以及发布版本中。然而,它不会在所有计算机上发生,但我已经能够在 Windows 7 和 XP 以及 .NET 框架 3.5 和 4.0 上复制此问题。

检查崩溃时进程在做什么,异常似乎是 GAC 部署的 DLL 上似乎有多个CreateFileMapping操作失败,结果为FILE LOCKED WITH ONLY READERS.

ProcMon 屏幕截图

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

现在,很明显我对正在发生的事情以及如何解决这个问题一无所知。如果你有线索,你能好心向我解释一下我正在处理什么类型的问题吗?

知道如何调试此问题吗?

4

1 回答 1

1

我正在使用除 ESRI 之外的其他地图控件,但我的设置非常相似:本机地图代码封装在 COM 中,封装在 Windows 窗体控件中,然后通过 WindowsFormsHost 引入 WPF 应用程序。几周前,当我单击我的地图时,我得到了完全相同的 System.AccessViolationException,帮助调试的选项很少。

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

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

所以,你可能有也可能没有类似的问题,但我会尝试跟踪初始化代码并查看传递给底层地图控件的参数值,看看它们是否有意义以及初始化是否正确在正确的时间以正确的值按您的预期发生。

祝你好运!

于 2011-03-31T13:24:22.570 回答