Reputation: 24227
Access will sometimes fail to exit cleanly and leave an MSACCESS.EXE process running with no visible user interface (the application is no longer shown in the Applications tab of Task Manager).
What is the minimal code necessary to reproduce this error?
UPDATE: I've posted an answer that reliably reproduces the problem. I would be very interested in other scenarios that may also reproduce the issue. I will upvote any future answer that successfully reproduces the problem. I would like to make this question a repository of verified scenarios that cause the issue so that those who run into this problem in the future have a better explanation then the usual vague suggestions to "close all open objects, etc."
Upvotes: 2
Views: 3177
Reputation: 24227
I've searched high and low for a reproducible example of this phenomenon and finally stumbled upon this answer posted by Chris from Brisbane, Australia: Something a little more subtle... I'm reposting his answer here with very slight modification:
Create a new form and add a single command button named cmdShutdown
with the following code:
Dim PersistentRS As DAO.Recordset
Private Sub Form_Open(Cancel As Integer)
Set PersistentRS = CurrentDb.OpenRecordset("SELECT * FROM msysobjects")
End Sub
Private Sub cmdShutdown_Click()
Application.Quit ' < This is the culprit.
End Sub
Private Sub Form_Close()
On Error GoTo ErrorHandler
ExitProcedure:
PersistentRS.Close ' < This is all it requires.
Exit Sub
ErrorHandler:
Resume ExitProcedure
End Sub
This problem is not about the PersistentRecordset being left open, quite the contrary. The fact is that the garbage collector has done its job and has already closed PersistentRecordset.
The garbage collector was called by Application.Quit before the Form_Close event was called.
Any Application.Quit command will call the garbage collector and it doesn’t matter if that command is on another Form.
Once the Application.Quit command has called the garbage collector all variables have been reset. The Application.Quit command then starts a shutdown sequence. If any Form is open then an attempt is made to close it. If the Form has a Form_Close or Form_Unload event those events will fire. When invoked by the Application.Quit command those events are running with PersistentRecordset which has already been closed.
So, if you are going to look for recordsets which have not been closed then save yourself some time. Look for recordsets where an attempt is made to close them and remove that attempt. We paid good money for the garbage collector so we should use it; it works. Trying to do the garbage collection ourselves can lead to failure.
But any such circular error, not just recordset errors, will cause Access to be too busy to close.
Chris.
I confirmed this reproduces the error in Access 2002 running in Windows 7 64-bit.
Upvotes: 1