Question

I'm trying to use the TimerCallback Delegate mechanism to drive instances of objects from a 3rd party .NET library component on separate threads executing on a timed basis.

When I try to create an instance of an object from the library I an exception is raised:

(object name) can only be called from a single-threaded apartment (STA)

The sub main which is the entry point for my application is marked MTAThread as in the Microsoft example on msdn here

Was it helpful?

Solution

Single-threaded COM components have a hard requirement that you create them on an STA thread. Which you create by using the [STAThread] attribute on your Main() method and by pumping a message loop. Such as the one created by Application.Run().

You can now call such a component from a worker thread or a timer callback. COM ensures that the single-threaded requirement for the component is met and marshals that call to the STA thread. Defeating what you were trying to accomplish, all calls to the component run on only one thread. You'll make it slower, not faster. Marshaling the call is not fast.

There is no secret sauce here, you cannot magically turn a component that explicitly stated that it doesn't support threading into a threaded component. Nor is it uncommon, the vast majority of COM components, or for that matter .NET components, do not support threading. The difference between COM and .NET components is that COM does something about it. A .NET component will typically just malfunction on some kind of threading race without a diagnostic.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top