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

在开发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(消息& m)      在System.Windows.Forms.Control.DefWndProc(消息& m)      在System.Windows.Forms.AxHost.WndProc(消息& 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 framework 3.5和4.0上复制此问题。 检查崩溃发生时的过程是什么,异常似乎是在GAC部署的DLL上似乎有多个
CreateFileMapping
操作失败,结果为
FILE LOCKED WITH ONLY READERS
。 此视图已被过滤以仅显示该类型的结果,但似乎每个DLL恰好发生两次。这是什么意思吗? 现在,很明显我对发生的事情毫无头绪,以及如何解决这个问题。如果你有一个线索,你能否善意并向我解释我正在处理什么类型的问题? 知道如何调试这个问题吗?     
已邀请:
我正在使用除ESRI之外的其他地图控件,但我的设置非常相似:用COM包装的本机地图代码,包装在Windows窗体控件中,然后通过WindowsFormsHost引入WPF应用程序。几个星期前,当我点击我的地图时,我得到了完全相同的System.AccessViolationException,只有很少的选项可以帮助调试。 我的问题的罪魁祸首:WPF中底层控件的初始化并没有像我想象的那样发生 - WPF推迟某些初始化,直到在屏幕上完全需要/可见视图(我假设减少窗口/控制加载时间) 。在WPF中,我将基础地图控件的所有初始化代码放入构造函数和(WPF)UserControl.Loaded事件处理程序中。问题是,WPF调用构造函数并在事物在屏幕上真正可见之前引发Loaded事件。所以我的底层地图控件正在初始化,表面大小为0高度,0宽度,这是合法的但不正确。当我点击地图时,我正在调用底层地图控件,将我的鼠标单击(x,y)转换为lat long,并引发了AccessViolationException。 我的解决方法是每当引发UserControl.Resize事件时使用新的表面大小重新初始化底层地图控件,这似乎在地图完全绘制到其正确大小之前可靠地发生,并在我的WPF中保留bool mapIsInitialized字段在地图初始化为非零表面大小之前,控件保持为假,设置了正确的投影,并且第一次完全绘制了地图。除非mapIsInitialized,否则我的函数(例如将屏幕点转换为lat lons)访问底层地图控件现在什么都不做。 所以,你可能有或没有类似的问题,但我会尝试跟踪初始化代码并查看传递给底层地图控件的参数的值,看看它们是否有意义,如果初始化是按照您的预期发生,在适当的时间使用适当的值。 祝好运!     

要回复问题请先登录注册