COM interface performance difference about DoWorkEventHandler(VB)

Li, Wennie 1 Reputation point
2022-04-29T07:40:49.667+00:00

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

VB
VB
An object-oriented programming language developed by Microsoft that is implemented on the .NET Framework. Previously known as Visual Basic .NET.
2,568 questions
{count} votes

1 answer

Sort by: Most helpful
  1. RLWA32 40,286 Reputation points
    2022-04-29T10:05:55.773+00:00

    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.

    2 people found this answer helpful.
    0 comments No comments