How to mark .NET objects exposed to COM-interop as single threaded?

你。 提交于 2019-12-09 10:51:45

问题


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.


回答1:


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 is not thread-safe and requires help from an STA thread. CoCreateInstance() uses this value when it creates the object. If necessary it will start an STA thread and create a proxy if the current thread is not STA, ensuring it is always used in a thread-safe way.

A [ComVisible] .NET class will be registered as "Both", indicating that it is okay to be used on a thread in the MTA. Pretty optimistic, but follows the .NET philosophy that everything is thread-unsafe but can be made safe by putting the lock keyword in the right places. A promise that is not often tested btw, risky. Overriding the ThreadingModel value (or omitting it) requires writing code to register the coclass yourself, decorated with the [ComRegisterFunction] attribute. RegistrationServices.RegisterTypeForComClients() can be useful to get the basic keys into place.



来源:https://stackoverflow.com/questions/2092523/how-to-mark-net-objects-exposed-to-com-interop-as-single-threaded

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!