简体   繁体   English

如何将暴露给COM-interop的.NET对象标记为单线程?

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

When defining a COM-visible class in C++ I can define the supported threading model in the header file (the threading(single) line): 在C ++中定义COM可见类时,我可以在头文件中定义支持的线程模型( threading(single) ):

[
    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)? 是否有类似的方法在.NET中设置线程模型(例如属性)? I currently define my COM-class as such: 我目前正在定义我的COM类:

[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. 看起来告诉RegAsm设置不同的ThreadingModel的唯一方法是编写一个用[ComRegisterFunction]属性标记的自定义注册方法。

That's really obscure, I've never seen the "threading" attribute in MIDL. 这真的很模糊,我从来没有见过MIDL中的“线程”属性。 Nor have the MSDN Library authors . 也没有MSDN Library的作者

A COM coclass publishes its threading requirements in the registry, using the HKCR\\CLSID\\{guid}\\InProcServer32 key. COM coclass使用HKCR\\CLSID\\{guid}\\InProcServer32密钥在注册表中发布其线程要求。 The ThreadingModel value declares the apartment it needs. ThreadingModel值声明它需要的公寓。 If it is missing or is set to "Apartment" then is announces that is not thread-safe and requires help from an STA thread. 如果它丢失或设置为“Apartment”,则宣布不是线程安全的并且需要来自STA线程的帮助。 CoCreateInstance() uses this value when it creates the object. CoCreateInstance()在创建对象时使用此值。 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. 如果当前线程不是STA,它将启动STA线程并创建代理,确保它始终以线程安全的方式使用。

A [ComVisible] .NET class will be registered as "Both", indicating that it is okay to be used on a thread in the MTA. [ComVisible] .NET类将注册为“Both”,表示可以在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. 非常乐观,但遵循.NET哲学,即一切都是线程不安全的,但可以通过将lock关键字放在正确的位置来使其安全。 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. 覆盖ThreadingModel值(或省略它)需要编写代码来自己注册coclass,用[ComRegisterFunction]属性修饰。 RegistrationServices.RegisterTypeForComClients() can be useful to get the basic keys into place. RegistrationServices.RegisterTypeForComClients()可用于将基本密钥放置到位。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM