【问题标题】:How to mark .NET objects exposed to COM-interop as single threaded?如何将暴露给 COM 互操作的 .NET 对象标记为单线程?
【发布时间】:2011-01-06 17:51:15
【问题描述】:

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

在 .NET 中设置线程模型是否有类似的方法(例如属性)?我目前这样定义我的 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
{
    ...
}

--编辑:

标记答案上的 cmets 是非常重要的。似乎告诉 RegAsm 设置不同的 ThreadingModel 的唯一方法是编写一个标有 [ComRegisterFunction]attribute 的自定义注册方法。

【问题讨论】:

    标签: c# .net com multithreading com-interop


    【解决方案1】:

    这真的很晦涩,我从未见过 MIDL 中的“线程”属性。 MSDN Library authors 也没有。

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

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

    【讨论】:

    • 我认为 OP 不是在谈论 MIDL 属性。 msdn.microsoft.com/de-de/library/zfbxt3zs.aspx
    • 我刚刚检查了注册表,ThreadingModel 的当前值为“Both”,这不是我要找的那个。除了使用标有 [ComRegisterFunction] 的方法手动注册 COM 类之外,是否还有另一种设置 ThreadingModel 的方法?
    • 我在 MSDN 中找到了其他信息(在“COM 客户端和 Windows Server 2003”下:msdn.microsoft.com/en-us/library/eaw10et3(VS.80).aspx)告诉我,RegAsm 注册的 .NET COM 服务器的默认 ThreadingModel 实际上是“两个都”。那么除了自己写一个 register 方法之外,没有其他方法可以告诉 RegAsm 使用另一个 ThreadingModel 吗?
    • 不,你必须写一个 [ComRegisterFunction]。
    • 这里是一个 ComRegisterFunction 设置线程模型的例子:stackoverflow.com/questions/5726624/…
    猜你喜欢
    • 2013-09-09
    • 1970-01-01
    • 2011-02-07
    • 1970-01-01
    • 2016-11-27
    • 2019-02-12
    • 1970-01-01
    • 2011-06-19
    • 1970-01-01
    相关资源
    最近更新 更多