如何将暴露给 COM 互操作的 .NET 对象标记为单线程? [英] How to mark .NET objects exposed to COM-interop as single threaded?

查看:15
本文介绍了如何将暴露给 COM 互操作的 .NET 对象标记为单线程?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在 C++ 中定义 COM 可见类时,我可以在头文件中定义支持的线程模型(threading(single) 行):

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")
]

在 .NET 中设置线程模型是否有类似的方法(例如属性)?我目前这样定义我的 COM 类:

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
{
    ...
}

--

对标记答案的评论是非常重要的.似乎告诉 RegAsm 设置不同的 ThreadingModel 的唯一方法是编写一个标有 [ComRegisterFunction] 属性的自定义注册方法.

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.

推荐答案

这真的很晦涩,我从未见过 MIDL 中的threading"属性.MSDN Library 作者也没有.

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

COM coclass 使用 HKCRCLSID{guid}InProcServer32 键在注册表中发布其线程要求.ThreadingModel 值声明了它需要的单元.如果它丢失或设置为Apartment",则宣布它不是线程安全的,需要 STA 线程的帮助.CoCreateInstance() 在创建对象时使用此值.如有必要,它会启动一个 STA 线程并在当前线程不是 STA 时创建一个代理,确保始终以线程安全的方式使用它.

A COM coclass publishes its threading requirements in the registry, using the HKCRCLSID{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.

[ComVisible] .NET 类将注册为Both",表示可以在 MTA 中的线程上使用.相当乐观,但遵循 .NET 哲学,即一切都是线程不安全的,但可以通过将 lock 关键字放在正确的位置来使其安全.顺便说一句,一个不经常测试的承诺是有风险的.覆盖 ThreadingModel 值(或省略它)需要编写代码来自己注册 coclass,并使用 [ComRegisterFunction] 属性进行修饰.RegistrationServices.RegisterTypeForComClients() 可用于获取基本密钥.

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.

这篇关于如何将暴露给 COM 互操作的 .NET 对象标记为单线程?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆