Microsoft KB Archive/176399

= PRB: VB5.0 OLE Automation Error --2147418107 (80010005) =

Article ID: 176399

Article Last Modified on 5/13/2003

-

APPLIES TO


 * Microsoft Visual Basic 5.0 Learning Edition
 * Microsoft Visual Basic 6.0 Learning Edition
 * Microsoft Visual Basic 5.0 Professional Edition
 * Microsoft Visual Basic 6.0 Professional Edition
 * Microsoft Visual Basic 5.0 Enterprise Edition
 * Microsoft Visual Basic 6.0 Enterprise Edition

-



This article was previously published under Q176399



SYMPTOMS
When a compiled Visual Basic application makes calls to an ActiveX server via a timer event, the following error may occur:

Run-time error '-2147418107 (80010005)': Automation error



CAUSE
After the first WM_TIMER event is fired, subsequent WM_TIMER events cannot be processed until the first event is completed. The error message equates to:

It is illegal to call out while inside message filter.



RESOLUTION
Three workarounds have been implemented with success:

Workaround 1
Set a boolean flag in the timer event (see code listed in the Steps to Reproduce Behavior section below).

 Select Project .Add Module and add a standard module  Type the following code into the module: Public flag As Boolean

  Change the Timer1_Timer event code to read as follows: Private Sub Timer1_Timer If Not flag Then flag = True RetStr = t.Test(100000) flag = False End If          Text1.Text = RetStr End Sub



By doing this, the timer can't call the server until the previous call is completed.

Workaround 2
Create the server as a DLL, not an EXE. ActiveX DLLs are in-process servers. An in-process server would not use Remote Procedure Call engine (RPC). (See the MORE INFORMATION below.)

Workaround 3
Place error handling in effect to ignore the error:

Private Sub Timer1_Timer On Error Resume Next RetStr = t.Test(100000) End Sub



STATUS
This behavior is by design.



MORE INFORMATION
Timers in Microsoft Windows are fired by Windows placing WM_TIMER messages in a windows message queue. For example, an application receives the first timer's WM_TIMER message in its window proc. This causes Visual Basic to fire the first timer's Timer event, which calls the ActiveX server through the Remote Procedure Call engine (RPC) because ActiveX EXE servers run in a separate process.

While the Visual Basic application is waiting for the RPC call to complete, the RPC engine allows the Visual Basic application to sit and poll its message queue. This is allowed primarily for screen redraw (if WM_PAINT messages come in because the user was switching around windows), so the application can update its windows while it is waiting for the RPC call to complete.

If, while Visual Basic waits for the first RPC call to complete, it processes a second WM_TIMER message coming in through the RPC message filter, this causes Visual Basic to fire the second timer's Timer event, which attempts to call the ActiveX server again through the RPC engine. However, the RPC engine explicitly does not allow an application to make an RPC call when it is in the RPC message filter, so it returns an error that Visual Basic returns to the user.

At the point at which Visual Basic gets the WM_TIMER message, there is no way for Visual Basic to know whether firing the Timer event will cause an RPC call to be made. In fact, because ActiveX servers can be transparently remote, there is no way for Visual Basic to know, when it is calling an object method, whether that method will be routed through the RPC engine. Thus, there is no way for Visual Basic to know ahead of time that the RPC engine is going to throw an error.

Steps to Reproduce Behavior
NOTE: The error will not reproduce unless you have compiled the projects.

Server
 Start a new ActiveX EXE project.</li>  Change the following properties: <pre class="fixed_text">     Project Name:TestDelayServer Class Name: cTestClass

</li>  Place the following code into cTestClass:

Option Explicit

Public Function Test(Optional delay As Long = 1000) as String Dim index As Long Dim Y As String Dim X As String Y = "a;lskdjf;laksdjf;lkasjd;flkajsmd;lfkjma;sldkfj;laskdj" For index = 1 To delay X = Right(Y, CInt(Len(Y) / 2)) X = "" Next Test = "I'm here" End Function

</li> Compile the EXE.</li> Run the EXE to register it.</li></ol>

Client
 Start a new Standard EXE.</li> Select TestDelayServer from the Project - References menu.</li> Insert a Command Button, Timer Control and TextBox Control.</li>  Place the following code into Form1's code window: Option Explicit

Dim t As New TestDelayServer.cTestClass Dim f As Form Public RetStr As String

Private Sub Command1_Click Set f = New Form1 f.Show End Sub

Private Sub Form_Load Timer1.Interval = 1000 Timer1.Enabled = True End Sub

Private Sub Timer1_Timer RetStr = t.Test(100000) Text1.Text = RetStr End Sub </li> Save the project.</li> Compile the EXE.</li> Run the compiled EXE. Note that the Automation error occurs.</li></ol>

Keywords: kberrmsg kbprb KB176399

-

[mailto:TECHNET@MICROSOFT.COM Send feedback to Microsoft]

© Microsoft Corporation. All rights reserved.