.NET Web Services and Visual FoxPro COM Object Threading Issues
One good reason to use .NET with Visual FoxPro is to publish Web Services. Since the SOAP Toolkit is severely limited in what types of services it can publish using .NET to handle exporting of services is fairly straight forward to do and many developers have surely gone that route.
But what you might not be aware of is that there’s a serious issue with Web Services when used with Visual FoxPro in that .NET Web Services run in Multithreaded Apartments (MTA) which means that they are running in a threading model that assumes that all code is multi-threaded. Visual FoxPro COM components however are Single Threaded (STA) and while they will load on MTA their behavior may become erratic if multiple instances are simultaneously executed. Essentially what happens is that in MTA threaded apartments .NET creates one STA thread on which all COM objects are then loaded which means:
- Only one COM object can execute at a time
- There’s potential for thread leakage as all of them share the same thread
and the same Thread Local Storage (TLS)
Which spells big problems for performance and can easily lead to corruption of data buffers and other global storage that VFP internally uses. In other words it doesn’t work out of the box.
I just ran into this with one of my customers who’s running a relatively small application that publishes some summary reports via a Web Service interface and they ended up getting some cross talk where data was getting mixed up between two clients. Ouch.
Unlike ASP.NET (ASPX) pages, Web Services in .NET do not have an ASPCOMPAT setting so you can’t easily coerce a Web Service request to be initiated on an STA thread. ASPCOMPAT cause ASP.NET to go through some internal thread management by basically offloading requests to a separate pool of threads made available by COM+ and running the requests of these STA threads instead. Alas, this functionality is not available directly for Web Services.
When I was researching this topic I ran into an MSDN article from Jeff Prosise which provides a hacky solution to this problem by creating a custom ASP.NET Handler for ASMX requests and routing it through the ASP.NET Page handler first. The Page handler includes methods to initiate requests on ASPCompat STA threads and his solution basically highjacks the page handler just for this functionality and then manually processes the Web Service request.
Here’s the code from handler Jeff’s article and I verified indeed that it works properly with VFP COM components:
using System;
using System.Web;
using System.Web.UI;
using System.Web.Services.Protocols;
using System.Web.SessionState;
public class AspCompatWebServiceStaHandler :
System.Web.UI.Page, IHttpAsyncHandler, IRequiresSessionState
{
protected override void OnInit(EventArgs e)
{
IHttpHandler handler =
new WebServiceHandlerFactory().GetHandler(
this.Context,
this.Context.Request.HttpMethod,
this.Context.Request.FilePath,
this.Context.Request.PhysicalPath);
handler.ProcessRequest(this.Context);
this.Context.ApplicationInstance.CompleteRequest();
}
public IAsyncResult BeginProcessRequest(
HttpContext context, AsyncCallback cb, object extraData)
{
return this.AspCompatBeginProcessRequest(
context, cb, extraData);
}
public void EndProcessRequest(IAsyncResult result)
{
this.AspCompatEndProcessRequest(result);
}
}
You need to add this class to your APP_CODE directory and then register the handler in Web.config:
<?xml version="1.0"?>
<configuration>
<system.web>
<httpHandlers>
<add verb="*" path="*.asmx"
type="AspCompatWebServiceStaHandler" />
</httpHandlers>
</system.web>
</configuration>
It ain’t pretty but it works. This makes your Visual FoxPro components run properly with ASMX Web Services. It’s a shame there’s not a flag somewhere on the ASMX handler to provide this, but so it goes…
Hopes this saves somebody some time…
Other Posts you might also like
- Adding minimal OWIN Identity Authentication to an Existing ASP.NET MVC Application
- Map Physical Paths with an HttpContext.MapPath() Extension Method in ASP.NET
- Resolving Paths To Server Relative Paths in .NET Code
- Back to Basics: Rewriting a URL in ASP.NET Core
- Getting the ASP.NET Core Server Hosting Urls at Startup and in Requests
The Voices of Reason
# re: .NET Web Services and Visual FoxPro COM Object Threading Issues
I just took a look at your post and the link back to the Adapter Pattern. Yuk... Talk about overkill for a simple problem. It's amazing what qualifies as 'pattern' these days.
I didn't actually try a COM+ component, but like you I'm wary to use them unless I really need to. The biggest issue though with COM+ is always performance which is usually considerably worse through COM+ than with raw STA apartments even though you do get better administration for the object.
# re: .NET Web Services and Visual FoxPro COM Object Threading Issues
# re: .NET Web Services and Visual FoxPro COM Object Threading Issues
Frankly it's been some time since I had to deal with COM+ and good riddance to that nightmare <s>... But COM issues still pop up here and there and this is important.
I wonder what the issues will be in relation to WCF...
# re: .NET Web Services and Visual FoxPro COM Object Threading Issues
>good riddance to that nightmare
Amen to that.
# re: .NET Web Services and Visual FoxPro COM Object Threading Issues
Just wondering if there is a better solution to this now or is it still an issue?
Thanks
John
# re: .NET Web Services and Visual FoxPro COM Object Threading Issues
Parser Error Message: Could not load type 'AspCompatWebServiceStaHandler'
When I try appending the , __code it also make no difference.
By the way should the AspCompatWebServiceStaHandler file have the .cs extension? Tried that too.
Any ideas help please?
# re: .NET Web Services and Visual FoxPro COM Object Threading Issues
# re: .NET Web Services and Visual FoxPro COM Object Threading Issues
If you can get away with using the old way you should use that. Otherwise you have some work ahead of you.
Here's an article that discusses this (more towards the end):
http://www.netfxharmonics.com/2009/07/Accessing-WPF-Generated-Images-Via-WCF
# re: .NET Web Services and Visual FoxPro COM Object Threading Issues
http://weblogs.asp.net/kdente/archive/2003/10/24/33370.aspx
And was very disappointed when it wasn't addressed in 2.0. We'd previously worked around the problem using Microsoft's original suggestion of sourcing the COM components out of a COM+ library application. It works, but Jeff's solution works even better.