Peterson's Ponderings

Technical findings, ideas, thoughts and news directly from me.
in

Threading model issues when using VB 6 COM components in a .NET Web Service

I recently encountered a very tricky issue with the threading model of .NET when you need to interop with a legacy VB 6 COM component.  The web service in question was created to consume components of a third party vendor that still distributed API functionality as a set of VB 6 COM dlls.  Each web service method utilized one or more calls into the VB 6 components to perform the desired functionality.  Initially everything appeared to be working properly under a light user load, but as soon as load increased on the application the web service response times began to vary drastically and in some instances slow to a crawl.  This was very perplexing as the call times varied so much it was hard to discern any sort of pattern.  The problem was narrowed down to be coming from the response time of method calls to the VB 6 components.  A trend was also noticed that the database connection for the VB 6 components was never exceeding 1 connection, which was odd considering there would be 20 ASP.NET calls in progress simultaneously and they were all utilizing the COM component.  To me this indicated some kind of bottleneck that seemed to be single threading the VB 6 COM component usage.  Slowly I began to remember my glorious (at the time) VB 6 days back in the late 90s and how VB 6 components are compiled to run in a single threaded apartment (STA).  After doing a quick search I found an excellent article from MSDN Magazine that described the exact same issues the problem web service was demonstrating.  The article explains how the issue arises from .NET running in a MTA (Multi-threaded apartment) and the way the OS is forced to run the COM components in a seperate STA space causing a queuing effect between the multiple ASP.NET threads trying to access the single COM component thread.  The solution is to get ASP.NET running in a STA mode as well so that the COM components can be loaded within each individual thread space of the ASP.NET processing threads removing the need to marshal across apartments.  This achieves what was the original desired result for the web service of having multiple seperate instances of the VB 6 component running concurrently for each web request.  The article gives a sweet implementation work around for .NET to get a web service running in STA mode instead of the default MTA.

I had to post this for as many people to see as possible because we all know VB 6 lives on and this hidden threading issue of using the legacy components from within a .NET web service is not a very apparent problem when it starts happening.  I hope this saves every developer from pulling out hair trying to isolate and resolve this issue!

Posted: Jan 17 2008, 09:59 PM by dpeterson | with 3 comment(s)
Filed under:

Comments

Kamran shahid said:

Nice article
# January 18, 2008 3:59 AM

Ken Codit said:

I encountered the same problem attempting to use VB6 COM components WCF.  The default threads created by WCF are multi-threaded apartments (MTA).  The legacy code I was attempting to expose was written in VB6 single threaded apartments (STA).  The following post by Scott Seely addressed the problem in a very nice way: blogs.catalystss.com/.../203.aspx

# March 5, 2008 4:00 PM

Jon said:

Any developers using Visual FoxPro COM DLL's from a .Net web service will run into this same problem.  But thankfully, they can implement this same workaround.

# May 22, 2008 8:25 AM
Leave a Comment

(required) 

(required) 

(optional)

(required)