在VB6 DLL模块中声明的变量意外重新初始化

时间:2009-12-21 11:05:58

标签: dll asp-classic vb6

我在一些ASP页面中嵌入了VB6 DLL。 DLL遇到了一个Codebase数据库,一个数据库引擎(一个方言/ dBase上的变体),这个数据库引擎几乎没有人听说过。 Codebase花了将近一秒时间来初始化一个新连接,这种速度慢得令人无法接受,所以我创建了一个由VB类管理的连接池。该类的单个实例是在VB模块的开头创建的,即:

Private m_codebaseManager As New CodebaseManager

我的问题是,定期再次调用类初始化方法会完全破坏我的池类,我不知道为什么。终止不会触发,并且没有发生任何崩溃的迹象,那么为什么在地球上初始化被称为?我的理解是非类模块中的数据在DLL的生命周期中持续存在。这是正确的,如果没有,在什么情况下模块'重启'?

3 个答案:

答案 0 :(得分:5)

我建议从变量声明中删除“New”。声明变量“As New”会导致每次引用它时都会检查它,如果设置为Nothing,则会创建CodebaseManager的新实例。

更好的解决方案是声明您的变量:

Private m_codebaseManager As CodebaseManager

然后在应用程序启动时将其显式设置为新实例:

Set m_codebaseManager = New CodebaseManager

这意味着您可以确定不会创建任何无意的CodebaseManager新实例。你可能仍然会有一个错误,但至少它将是一个“对象或没有设置块变量”错误,你应该能够轻松修复。

答案 1 :(得分:1)

  
    

我的理解是非类模块中的数据在DLL的生命周期中仍然存在。这是正确的,如果没有,在什么情况下模块'重启'?

  

排序。全局状态(模块公共/私有变量)是特定于公寓的,并存储在TLS插槽中。 VB6仅支持单元线程,因此每个线程都获得全局状态的“新”副本。因为ASP环境是多线程的,所以每个线程都有一个单独的数据库连接“池”。

如果需要真正的全局状态,则必须使用Application对象来存储它。如果你把公寓线程对象放在那里(比如VB6),这些可以序列化多线程ASP环境并降低性能。使用ADO对象或Dictionary对象或您确定的任何自由线程。

顺便说一下,你可以让COM +为你做对象/连接池。如果OLEDB提供程序是更好的,它也可以在内部进行连接池(SQLOLEDB for MSSQL就是一个例子)。

答案 2 :(得分:0)

但它是一个DLL而不是ActiveX exe,所以没有Main()函数,除了全局范围外,'Set m_codebaseManager = New CodebaseManager'行无处可去。