FIX: Handle Leak when Passing ADO Objects Between Processes
ID: Q197426
|
The information in this article applies to:
-
ActiveX Data Objects (ADO), versions 2.0, 2.1 SP2
SYMPTOMS
When marshalling an ActiveX Data Objects (ADO) recordset between processes
the handle count incrementally increases for each call made to the out-of-
process component. This behavior only occurs if the rowset contains more
than 8K of data.
CAUSE
This is a problem in ActiveX Data Objects
Version 2.0.
RESOLUTION
A supported fix that corrects this problem is now available from Microsoft, but
it has not been fully regression tested and should be applied only to systems
experiencing this specific problem. If you are not severely affected by this
specific problem, Microsoft recommends that you wait for the next
that contains this fix.
To resolve this problem immediately, contact Microsoft Product Support Services
to obtain the fix. For a complete list of Microsoft Product Support Services
phone numbers and information on support costs, please go to the following
address on the World Wide Web:
http://www.microsoft.com/support/supportnet/overview/overview.asp
STATUS
Microsoft has confirmed this to be a bug in the Microsoft products listed
at the beginning of this article.
This problem has been fixed in Microsoft ActiveX Data Objects versions 2.1 and later.
You can install the latest version of Microsoft Data Access Components from the following Web site:
http://www.microsoft.com/data/download.htm
MORE INFORMATION
Steps to Reproduce the Behavior
NOTE: The following steps assume that you are using Visual Basic 5.0 or
later.
- Build an ActiveX .EXE that creates a disconnected recordset with ADO
2.0.
- Use the following SQL statement against the Pubs (SQL Server 6.5)
database to produce a recordset that contains more than 8K of data:
(SELECT authors.*, roysched.*, titleauthor.*, titles.*, publishers.*
FROM titleauthor INNER JOIN authors ON titleauthor.au_id =
authors.au_id INNER JOIN titles ON titleauthor.title_id =
titles.title_id INNER JOIN roysched ON titles.title_id =
roysched.title_id INNER JOIN publishers ON titles.pub_id =
publishers.pub_id).
- Pass the recordset as the return value of a function in the .exe.
Here is sample code for a function that returns an ADODB recordset, using the SQL above:
Public Function GetRs() As ADODB.Recordset
Dim cn As ADODB.Connection
Dim Rs As ADODB.Recordset
Dim strsql As String
Set cn = New ADODB.Connection
cn.Open "dsn=pubs"
Set Rs = New ADODB.Recordset
strsql = "(SELECT authors.*, roysched.*, titleauthor.*, titles.*, " & _
"publishers.* FROM titleauthor INNER JOIN authors ON " & _
"titleauthor.au_id = authors.au_id INNER JOIN titles ON " & _
"titleauthor.title_id = titles.title_id INNER JOIN roysched ON " & _
"titles.title_id = roysched.title_id INNER JOIN publishers ON " & _
"titles.pub_id = publishers.pub_id)"
Rs.CursorLocation = adUseClient
Rs.LockType = adLockBatchOptimistic
Rs.Open strsql, cn
Set Rs.ActiveConnection = Nothing
Set GetRs = Rs
cn.Close
Set cn = Nothing
End Function
- Create a client application that creates an instance of the .exe and
calls the recordset returning function from the .exe.
- It is important to maintain the scope of the .exe between calls.
- Repeat the call process to the .exe several times.
Here is sample code that repeatedly calls a function that returns an ADO recordset from an ActiveX EXE named rsEXE, within the scope of a single procedure:
Dim rs1 As ADODB.Recordset
Dim rs2 As ADODB.Recordset
Dim rs3 As ADODB.Recordset
Set rs1 = New ADODB.Recordset
Set rs2 = New ADODB.Recordset
Set rs3 = New ADODB.Recordset
Dim gs As RsEXE.rs
Set gs = New RsEXE.rs
'Add rsEXE to Performance Monitor before executing the next line
Set rs1 = gs.GetRs
Set rs2 = gs.GetRs
Set rs3 = gs.GetRs
rs1.Close
rs2.Close
rs3.Close
Set rs1 = Nothing
Set rs2 = Nothing
Set rs3 = Nothing
Set gs = Nothing
- Step through the client application:
- After creating the ActiveX EXE object, but before calling the function
that returns a recordset, open Windows NT Performance Monitor.
- In Performance Monitor, choose Edit, Add to Chart.
- For Object, choose Process.
- For Counter, choose Handles.
- For Instance, choose the now running ActiveX EXE.
- Return to stepping through the client application.
While stepping through the client, check the handle count for the ActiveX EXE in Performance Monitor.
You will see the handle count increase by 2(+/-1) for each call you make to the component.
Additional query words:
Keywords : kbADO200bug kbADO200fix kbADO210fix kbDatabase kbGrpVBDB kbGrpMDAC kbDSupport kbADO200QFE kbMDAC210fix kbMDAC210SP2
Version : WINDOWS:2.0,2.1 SP2
Platform : WINDOWS
Issue type : kbbug