I have a little c# class that I need to expose as COM. THe tool that will use the COM object requires that I support STA. Is there anything special that I need to do with my COM object?
(I know about the STAThread attribute, but (unless I'm wrong开发者_如何学Go) It is for indicating that a thread of execution in .net is to be STA compatible, and not for indicating that my COM object needs to be compatible).
Here's my declaration so far. Do you see anything that I need to add?
[ComVisible(true)]
[ClassInterface(ClassInterfaceType.None)]
[ComDefaultInterface(typeof(ITestClass1))]
[Guid("093A3701-2C53-4A31-97C5-0F3C205E5B4C")]
public class Class1: ITestClass1 {..}
[ComVisible(true)]
[Guid("8D52F785-CDD8-4248-8AB7-97B8C19DE59B")]
public interface ITestClass1 {..}
A COM server advertises the threading model it requires with a registry entry named ThreadingModel. Single threaded is the default if the registry key is missing or when it is set to "Apartment".
Regasm.exe sets this key to "Both". Which means that your server is declared to be compatible with both STA threads and MTA threads. Somewhat in keeping with .NET code in general, it supports threading but with the requirement that you have to take care of thread-safety. Changing this is very awkward, you have to write your own registration procedure and annotate it with the [ComRegisterFunction] attribute.
The simple approach is leave the key set to "Both" and to check the apartment state in your class constructor. Use Thread.GetCurrentThread().GetApartmentState(). If you get MTA then throw an exception to tell the client that you don't support multi-threading. Lots of .NET classes do this.
See this answer for an example of a ComRegisterFunction that does the necessary registry voodoo. There are a few cases where you might want this - e.g. when you want to ensure that your threads are STA so you can interact with other COM objects that require use only by STA threads.
精彩评论