它可能挂起的另一个原因是因为 VB6 正在等待数据库。您在数据库上运行的查询是长时间运行的,还是需要很长时间的 VB6 代码?
如果数据库查询导致问题并且您使用的是 ADO,则可以使用异步数据库连接。代码的逻辑可能会更复杂,因为您必须设置回调方法才能在每个数据库调用完成后继续处理。
你可以像这样建立这样的连接:
Private WithEvents m_conn As ADODB.Connection
...
Set m_conn = New ADODB.Connection
Call m_conn.Open(connectionString, , , adAsyncConnect)
像这样执行查询/存储过程 - 您会注意到这里的主要区别是,在查询完成之前不会挂起,而是继续正常执行代码):
sql = "SELECT Col1 FROM etc. etc."
Call m_conn.Execute(sql, , adAsyncExecute)
像这样取消正在运行的查询:
Call m_conn.cancel
以及查询完成时的所有重要回调:
Private Sub m_conn_ExecuteComplete(ByVal RecordsAffected As Long, ByVal pError As ADODB.Error, adStatus As ADODB.EventStatusEnum, ByVal pCommand As ADODB.Command, ByVal pRecordset As ADODB.Recordset, ByVal pConnection As ADODB.Connection)
... do more processing etc...
End Sub
您可能会发现上述内容对于您想要的东西来说太过分了;我只是自己实现的,因为该窗口是专门为执行长时间运行的查询而设计的,并且窗口保持响应并允许在中途取消查询非常重要。
不过,据我所知,如果您不使用异步查询方法,VB6 将保持无响应,直到您的m_conn.Execute 方法返回。
如果由于 VB6 代码本身而发生延迟 - 例如在您创建临时表的所有工作中,那么我会同意 MarkJ 的“经典”答案并使用 DoEvents - 尽管看似笨拙的机制,它确实工作得很好。在整个过程中撒上一些,您应该会注意到一些改进。虽然可能并不完美,但可能已经足够了。
例如
retrieve results
...
DoEvents
...
build temporary tables
...
DoEvents
每次点击 DoEvents 块之一时,如果用户单击了代码应该触发的“取消”按钮。
注意:您可能还想对在代码仍在运行时卸载表单有点谨慎,我不相信一切都会正确卸载。在这种情况下,您可能想要这样的东西:
Private m_cancel as Boolean
Private Sub cmdCancel_Click()
m_cancel = True
End Sub
Private Sub cmdProcess_Click()
...
retrieve results
...
DoEvents
If Not m_cancel Then
... build temporary tables etc...
End if
If m_cancel Then Unload Me
End Sub