2011-10-27 40 views
0

最近我们使用结构化编程技术重写了一个工作原型库以实现可维护性。它使用应用程序的基于COM的API从第三方应用程序(TPA)访问数据。该API使用Win32消息传递(WM_COPYDATA)与TPA进行通信。AccessViolationException在使用COM互操作的.NET应用程序中随机发生

新的库代码:

  1. 是用C#和Visual Studio 2010 SP1。
  2. 面向.NET Framework 4(原型中为3.5)。
  3. 使用匿名方法和新的自定义泛型类来分解和简化原始代码,该代码不使用(除少数.NET Framework实用程序类型外,如HashSet <>)。
  4. 使用非嵌入互操作类型(Embed Interop Types = False)和免注册COM(Isolated = True)引用基于COM的API。
  5. 将Marshal.ReleaseComObject用于基于COM的API返回的对象的确定性内存管理。
  6. 仅在单线程单元(基于COM的API为单元线程)中运行的工作线程上使用基于COM的API。
  7. 调用基于COM的API时使用早期绑定。

我们的测试应用程序崩溃随机地基于COM的API中AccessViolationException。堆栈跟踪显示这发生在调用UnsafeNativeMethods.DispatchMessageW(请参阅下面的示例)或基于COM的API中的几个不同属性中的任何一个。测试人员应用程序是一个带有菜单,状态栏和RichTextBox的简单WinForms应用程序。

此行为是常见的Windows XP和Windows 7,辅助线程和UI线程之间是否线程间通信已启用,我们是否通过FinalReleaseComObject更换ReleaseComObject的。当TPA非常繁忙时,它似乎更频繁地崩溃,例如。而它正在启动。

原型库使用VS 2008项目转换为VS 2010年后开发,原型应用程序仍然不会崩溃。

System.AccessViolationException未处理消息=尝试到 读取或写入受保护的内存。这通常表示其他 内存已损坏。源= System.Windows.Forms的堆栈跟踪: 在System.Windows.Forms.UnsafeNativeMethods.DispatchMessageW(MSG & MSG) 在System.Windows.Forms.Application.ComponentManager.System.Windows.Forms.UnsafeNativeMethods.IMsoComponentManager.FPushMessageLoop(IntPtr的 dwComponentID,的Int32原因,的Int32 pvLoopData) 在System.Windows.Forms.Application.ThreadContext.RunMessageLoopInner(的Int32 原因,ApplicationContext的上下文) 在System.Windows.Forms.Application.ThreadContext.RunMessageLoop(的Int32 原因,ApplicationContext的上下文) 在System.Windows.Forms.Application.Run(表格的MainForm) 在IndexerTester.Program.Main()中d:\ TestApps \索引\ IndexerTester \ Program.cs的:线17

你见过类似的问题?

您可以提供有关隔离原因和/或潜在解决方法的任何建议吗?

+1

调用堆栈显示正在从工作线程封送到主线程的调用。如果您在该STA线程上创建COM对象,则您的STA才能正常工作。但这不太可能是问题所在,本机代码很少需要C#程序对AV进行轰炸的帮助。你看不到任何东西,因为你没有启用非托管调试。 –

+0

谢谢,我不知道这个调用堆栈代表了线程间编组。不幸的是,我没有经历过非托管调试。我不确定我能否使用它,因为我无法访问COM源代码或其PDB文件。你能建议一些资源来学习如何做到这一点? – groverboy

+0

如果没有这些资源,你几乎没有可能。编写单元测试来重现崩溃。然后将其发送给代码所有者,让他帮助你。 –

回答

0

这有点晚了,但可能有助于某人。

我们向COM对象的供应商发送了一个错误报告:当使用两个实例时,会发生AccessViolationException,每个实例都在不同的线程上。供应商确认其代码中存在一个错误(一个非线程安全的静态变量)并发布了修正。

我们注意到,当第三方应用程序(TPA)和我们的测试应用程序(从TPA读取数据)都很忙时,崩溃更频繁。至关重要的是,我们发现,在工作量很大的情况下,使用原型应用程序也会发生崩溃事件;我们错误地认为我们的重写引入了一个错误。这一发现说服我们向供应商汇报。

相关问题