ASP.NET and STA COM objects

2020-04-17 19:13发布

问题:

Looking to settle an argument here.

All the stuff I've read on using a COM object created in VB from an ASP.NET page is surrounding with

WARNING - MAKE SURE YOU PUT ON ASPCOMPAT OR IT WON'T WORK

http://books.google.co.uk/books?id=-sjg09Crh40C&lpg=PA771&ots=g-vqDun9TR&dq=asp.net%20c%23%20sta&pg=PA771#v=onepage&q=&f=false

However... I have set this up and guess what - no problems.

Now, I read this

http://msdn.microsoft.com/en-us/library/zwk9h2kb.aspx

and

http://blogs.claritycon.com/blogs/don_peterson/archive/2008/01/17/3621.aspx

Which suggests that you won't get an exception, it just won't work very well.

Could anyone give a definitive answer to what is going on?

Also, if there's any way that I could PROVE the switch between MTA and STA (through some debugger magic - even looking at the assembler!) I'd be grateful.

Cheers Duncan

回答1:

Sure you can use a VB COM component in an ASP.NET application. You think that millions of lines of VB code aren't going to get any love in .NET-land? :)

VB COM components are notorious for being compiled using a Single Threaded Apartment (STA) - though not always the case (if I remember correctly).

When using a STA VB component in .NET you might find that you experience:

  1. Slower performance
  2. Possible memory leak due to blocked finalizer (not trying to be all doom and gloom, just seems to happen more often than not)
  3. Hair loss

An easy way to determine MTA v. STA for a thread is to leverage Windbg, connect to the process, load SOS, and execute !threads. You'll see output similar to:

0:015> !threads
ThreadCount: 27
UnstartedThread: 0
BackgroundThread: 17
PendingThread: 0
DeadThread: 10
Hosted Runtime: no
                                      PreEmptive   GC Alloc           Lock
       ID OSID ThreadOBJ    State     GC       Context       Domain   Count APT Exception
  15    1  a28 000d75f0   1808220 Enabled  3823b58c:3823bb08 000d3fe8     0 STA (Threadpool Worker)
  19    2  43c 000dd5f0      b220 Enabled  00000000:00000000 000d3fe8     0 MTA (Finalizer)
  20    3  b94 000f20b0    80a220 Enabled  00000000:00000000 000d3fe8     0 MTA (Threadpool Completion Port)
  21    4  15c 000f5318      1220 Enabled  00000000:00000000 000d3fe8     0 Ukn

Note that one of threads has "STA" listed in the APT column. This thread is a STA thread and your likely to see your VB COM code on its call stack.

References discussing the problem:

  • COM Interoperability in the .NET Framework
  • Running ASMX services on STA Threads
  • Developing High Performance ASP.NET Websites
  • ASP.NET Hang and OutOfMemoryException caused by STA Components
  • Debugging Tools for Windows

Good Luck!
Z



回答2:

If you can modify the source of the COM object, you may be able to determine if its behaving as an STA through a simple experiment assuming you have a test environment.

  1. Call sleep for some significant amount of time in the component, say 30 seconds and deploy the component.

  2. Fire up a couple of browsers and hit the page requiring the component from two browsers at about the same time.

  3. Assuming the page has no other significant non-deterministic delays, you should be able to tell if this is a MTA or STA. If both pages return at the same time ( after about 30 seconds ), the component is running as an MTA. If one returns in 30 and the other in 60, its running as an STA.

I would think that there is a way to inspect the registry or the dll itself as well, but it has been a little while since I was working in a mixed COM / ASP.NET world.

Good luck!



标签: asp.net com