views:

232

answers:

1

When defining a COM-visible class in C++ I can define the supported threading model in the header file (the threading(single) line):

[
    coclass,
    default(IComInterface),
    threading(single),
    vi_progid("Example.ComClass"),
    progid("Example.ComClass.1"),
    version(1.0),
    uuid("72861DF5-4C77-43ec-A4DC-ED04396F0CCD")
]

Is there a comparable way of setting the threading model in .NET (for example an attribute)? I currently define my COM-class as such:

[Guid("67155A91-2948-43f5-B07F-5C55CDD240E5")]
[ComVisible(true)]
[InterfaceType(ComInterfaceType.InterfaceIsDual)]
public interface IComInterface
{
    ...
}


[Guid("DC5E6955-BB29-44c8-9FC0-6AADEEB2AFFB")]
[ClassInterface(ClassInterfaceType.None)]
[ProgId("Example.ComClass")]
public class ComClass : IComInterface
{
    ...
}

--edit:

The comments on the marked answer are the really important thing. It seems like the only way to tell RegAsm to set a different ThreadingModel is to write a custom registration method marked with the [ComRegisterFunction]attribute.

+3  A: 

That's really obscure, I've never seen the "threading" attribute in MIDL. Nor have the MSDN Library authors.

A COM coclass publishes its threading requirements in the registry, using the HKCR\CLSID{guid}\InProcServer32 key. The ThreadingModel value declares the apartment it needs. If it is missing or is set to "Apartment" then is announces that it needs STA. CoCreateObject() uses this value when it creates the object. It will create a proxy if the current thread is not STA.

Writing custom registry values is a bit awkward in .NET, you'd have to use the [ComRegisterFunction] attribute and take over the duties of Regasm.exe.

Hans Passant
I think the OP is not talking about MIDL attributes. http://msdn.microsoft.com/de-de/library/zfbxt3zs.aspx
Henrik
You're right. It doesn't change my answer.
Hans Passant
I just checked the registry and the current value for ThreadingModel is "Both", which isn't the one I'm looking for. Isn't there another way of setting the ThreadingModel besides manually registering the COM-classes using a method marked with [ComRegisterFunction] ?
Xperimental
I found additional information in the MSDN (under "COM Client and Windows Server 2003": http://msdn.microsoft.com/en-us/library/eaw10et3(VS.80).aspx) telling me, that the default ThreadingModel for .NET COM-servers registered by RegAsm is in fact "Both". So is there no other way of telling RegAsm to use another ThreadingModel besides writing a register method of my own?
Xperimental
No, you'll have to write a [ComRegisterFunction].
Hans Passant
Ok. Too bad... but thanks.
Xperimental