2

我正在处理的 VB.NET 应用程序中的内存访问异常存在一些问题。我希望在这里获得一些见解,因为我所做的任何研究都没有帮助我找到问题所在。

背景:

我正在将许多应用程序从 VB6 转换为 .NET 4.0。应客户的要求,我正在进行直接转换,并且仅在必要时进行重构,以避免在转换时将其他问题注入代码中。大多数应用程序都在任何 CPU 模式下编译,但由于依赖 32 位 PLC 软件或较旧的硬件驱动程序,一些应用程序必须编译为 x86。我的开发机器是 Windows 7 64 位。

问题:

成功转换两个应用程序后,第三个应用程序在代码中的随机位置崩溃。未捕获异常,我必须查看查看事件日志,我在 ntdll.dll 上看到异常代码:0xc0000005,我认为这是内存访问异常。由于应用程序并不总是在同一个地方崩溃,因此很难追踪。我注意到在调用 ADODB 期间会发生很多错误(并不总是在同一个地方或在同一个调用中),但它在调用 form.ShowDialog() 时也会崩溃。

调用 ShowDialog 的表单使用 ADODB 将一些日志信息写入数据库。虽然我无法确认,但我猜测 form.ShowDialog() 中的异常是在这些 ADODB 调用之一期间发生的。ADODB 调用的崩溃发生在已在已转换的其他两个应用程序中成功使用的程序集中,并且它不会始终在同一个地方崩溃。

在我对此的研究中,我发现糟糕的互操作会导致这个问题。想知道 ADODB COM 调用是否在某种程度上导致了这个应用程序中的问题,即使这些调用在其他应用程序中都很好。

我观察到的一些地方显然将这个异常抛出到事件日志中:

  • 新建 ADODB.recordset
  • 在 command.append 中创建新参数
  • connection.open 调用

有人知道我如何缩小范围以可能将问题追溯到其根本原因吗?感谢您提供的任何帮助或见解。

4

1 回答 1

0

啊... PLC 让我回来了。如果制造商没有更新的驱动程序集,您可能正在打一场艰苦的战斗。可能发生的情况是较新的操作系统更快或具有更多内核,或者两者的某种组合导致驱动程序代码中的“竞争”条件。在经常使用线程的通信中尤其如此。由于驱动程序代码可能是用 C 或 C++(非托管)编写的,因此您可能无法控制这些条件。您可以尝试弄乱应用程序正在运行的线程模型。如果这样可以提高稳定性,那就去吧。

Visual Basic 6 中的单元模型线程

DotNet MTA 线程属性

DotNet STA 线程属性

最坏的情况是,您可以生成一个使用驱动程序的单独进程,并使用各种“进程间通信”技术从您的主应用程序与其通信。如果它崩溃了,你会启动另一个,但你的主应用程序仍然会继续运行。您甚至可以在绝对最坏的情况下将外部进程编写为 VB6 应用程序。

祝你好运。

于 2012-10-31T13:59:05.470 回答