views:

35

answers:

1

Setup -- Create a simple COM addin through DOTNET/C# that does nothing but sleep on the current thread for 5 seconds.

namespace ComTest
{
    [ComVisible(true)]
    [ProgId("ComTester.Tester")]
    [Guid("D4D0BF9C-C169-4e5f-B28B-AFA194B29340")]
    [ClassInterface(ClassInterfaceType.AutoDual)]
    public class Tester 
    {
        [STAThread()]
        public string Test()
        {
            System.Threading.Thread.Sleep(5000); 
            return DateTime.Now.ToString();
        }

    }
}

From an ASP page, call the test component:

<%@ Language=VBScript %>
<%option explicit%>
<%response.Buffer=false%>

<%



 dim test
 set test = CreateObject("ComTester.Tester")


%>

 <HTML>
 <HEAD></HEAD>
 <BODY>
  <%
  Response.Write(test.Test())
  set test = nothing

  %>

 </BODY>
 </HTML>

When run on a windows 2003 server, the test.asp page blocks ALL OTHER threads in the site while the COM components sleeps.

How can I create a COM component for ASP that does not block all ASP worker threads?

A: 

I would say what is very likely happening here is that all web requests are getting serialized somewhere. It is difficult tell exactly where this is happening, but there are a couple of possibilities.

  • Your COM object lives in a single threaded apartment and is being shared between web requests somehow. COM objects that live in an STA will have calls originating from threads other than the thread that created them marshalled onto the creating thread. The effect is that callers from different threads must wait in line to execute Tester.Test.

  • The ASP requests are somehow being serialized. Based on my understanding of how ASP is suppose to work I am having difficulty envisioning how that would happen. Maybe you have an ASP.NET page with AspCompat set to true and that causes them to share the same apartment. I am really grasping here, but either way I would say your problem is related to the behavior of STA COM objects.

Brian Gideon