question

LiWennie-0593 avatar image
0 Votes"
LiWennie-0593 asked RLWA32-6355 commented

COM interface performance difference about DoWorkEventHandler(VB)

We found that if a COM interface is called inside the DoWorkEventHandler, it will cost more time than the time spent outside.

For example, we first create and expose a com interface like following.



STDMETHODIMP_(HRESULT __stdcall) CTemp::Number1(LONG * __result)

{

 *__result = 1;

 return S_OK;

}



And then, call Number1 in a VB project like follwing.



Imports System.ComponentModel

Imports System.IO

Imports System.Runtime.InteropServices

Public Class MainForm

 Public Sub New()

     InitializeComponent()

 End Sub

 Private Sub MainForm_Shown(sender As Object, e As EventArgs) Handles MyBase.Shown

 End Sub

 Private Sub btnRun_Click_async(sender As Object, e As EventArgs) Handles btnRun.Click

     btnRun.Enabled = False

     Dim stopwatch As New Stopwatch

     Dim oTestCalss As New ComTestLib.Temp

     For t = 1 To 10000

         stopwatch.Start()

         oTestCalss.Number1()

         stopwatch.Stop()

     Next

     MsgBox(String.Format("OutDoWork::Measured elapsed time is {0}.", stopwatch.Elapsed.ToString("mm\:ss\.fff")))

     stopwatch.Reset()

     Dim doWorkHandler As DoWorkEventHandler =

         Sub()

             For t = 1 To 10000

                 stopwatch.Start()

                 oTestCalss.Number1()

                 stopwatch.Stop()

             Next

             MsgBox(String.Format("InDoWork::Measured elapsed time is {0}.", stopwatch.Elapsed.ToString("mm\:ss\.fff")))

         End Sub

     stopwatch.Reset()

     AddHandler BackgroundWorker.DoWork, doWorkHandler

     BackgroundWorker.RunWorkerAsync()

 End Sub

End Class




The result is shown in the attachment. No matter 32bit com or 64bit com, calling 10,000 times com interface out of the handler will only cost few milliseconds, but in the handler, it takes more time obviously.



So, the question is, why is there such a big performance difference between calling the com interface inside and outside the DoWorkEventHandler?
197658-performance.jpg


dotnet-visual-basic
performance.jpg (26.9 KiB)
· 1
5 |1600 characters needed characters left characters exceeded

Up to 10 attachments (including images) can be used with a maximum of 3.0 MiB each and 30.0 MiB total.

Was your question answered? Do you have any further issues?

0 Votes 0 ·

1 Answer

RLWA32-6355 avatar image
1 Vote"
RLWA32-6355 answered RLWA32-6355 edited

It is likely that your in-process COM object is instantiated in the same STA (Single-threaded Apartment) that contains the main UI thread of the Windows Forms application. However, the thread that is used by a backgroundworker component does not live in the STA the contains your COM object. By default it will be in COM's MTA (Multithreaded Apartment). The short story is that COM rules require that all calls to COM objects in the STA from other apartments must be marshaled back to their thread in the STA. This inter-apartment marshaling introduces additional overhead that is reflected in the performance of the backgroundworker compared to when the COM methods are called from within the STA.

And the posted code doesn't make sense to me. The COM method takes a LONG* argument but the VB call to the COM method doesn't pass any parameters.

5 |1600 characters needed characters left characters exceeded

Up to 10 attachments (including images) can be used with a maximum of 3.0 MiB each and 30.0 MiB total.