如果这些是用 VB6 编写并用于桌面应用程序的,那么显示表单是您遇到的最小问题。这些 COM 对象可能也不希望被多个线程同时访问。这可以非常壮观或非常微妙地爆炸。
如果管理层依靠这一点为 10,000 个图书馆工作,那么您需要让他们明白,违反 10,000 段十年前代码的假设并不是一个好主意。
如果管理层足够老了(并且在美国),那么请提醒他们关于“愚弄大自然母亲不是好”的旧 margerine 广告。坏事可能会发生。
我认为我需要更具体地了解“坏事”。
我假设这些是为与一个或多个 VB6 表单应用程序交互而创建的 VB6 COM 对象。然后这些 COM 对象可以合理地假设一次只有一个线程访问它们,一次只有一个用户访问它们,实际上只有一个线程和一个用户在它们的整个生命周期中访问它们。
一旦你在服务器上运行它们,你就违反了他们的假设。
谁能说出这会导致什么?没有人会进行这种分析,因为它们是基本(且有效)的假设!代码可能会在线程本地存储中缓存一些东西吗?这将适用于原始场景。也许共享数据用于缓存信息。如果要被多个线程使用,则需要互锁,然后您必须希望每个用户的信息不会有所不同,因为不同的线程可能代表不同的用户运行。
曾经有人告诉我去修复内存泄漏。长话短说,这不是内存泄漏。它是一段遗留的非托管代码,假设它在桌面或批处理应用程序中运行。在 Web 服务中,它在整个堆中喷吐垃圾。因此,它到处抛出异常,并导致其他不相关的代码也这样做。非托管异常没有提供太多细节,因此无法查看导致问题的原因或解决方法。
在这种情况下,我可以简单地在所有访问权限周围设置一个互锁。这已经足够好了,因为这段代码假定了一个批处理环境,而不是一个交互式环境。如果您的 COM 对象假设他们十年前的要求没有从它们下面改变,那么这可能还不够。
如果所有 COM 对象都可以在一个用户身份下运行,那你就省了一大笔麻烦。除此之外,您可能只需要确保给定对象一次只有一个实例,并且对它的所有访问都是序列化的。为此,请在 VB.NET 中使用 SyncLock 语句。
最终的解决方案是对代码进行“测试驱动移植”。我会使用现有的代码库来创建自动化单元测试(也许使用vbunit)。一旦一段代码具有足够的单元测试覆盖率,您就可以将该代码(仍作为 COM 对象)移植到 VB.NET。单元测试可用于确认端口仍在工作。
这样的移植可能没有您想象的那么难。 “复制和粘贴并修复编译器错误”在 VB6 和 VB.NET 之间运行良好。甚至有工具可以提供帮助。但正是自动化测试使这变得实用。否则,您会合理地担心移植的效果。
请注意,新的 COM 对象仍应可供原始 VB6 代码使用。事实上,这应该是一个测试。
还请注意,这将是一个记录移植代码的好机会,这样在接下来的十年中这将不再是一个问题。只是不要丢失文档!