将类公开为STA COM

时间:2010-07-19 15:28:25

标签: c# .net com

我有一个小c#类,我需要公开为COM。使用COM对象的工具要求我支持STA。我需要对COM对象做些什么特别的事情吗?

(我知道STAThread属性,但是(除非我错了)它用于指示.net中的执行线程是STA兼容的,而不是用于指示我的COM对象需要兼容)

到目前为止,这是我的声明。你看到我需要添加什么吗?


    [ComVisible(true)]
    [ClassInterface(ClassInterfaceType.None)]
    [ComDefaultInterface(typeof(ITestClass1))]
    [Guid("093A3701-2C53-4A31-97C5-0F3C205E5B4C")]
    public class Class1: ITestClass1 {..}

    [ComVisible(true)]
    [Guid("8D52F785-CDD8-4248-8AB7-97B8C19DE59B")]
    public interface ITestClass1 {..}

2 个答案:

答案 0 :(得分:7)

COM服务器使用名为ThreadingModel的注册表项通告所需的线程模型。如果缺少注册表项或将其设置为“Apartment”,则单线程是默认值。

Regasm.exe将此密钥设置为“Both”。这意味着您的服务器被声明为与STA线程和MTA线程兼容。有点与.NET代码保持一致,它支持线程,但要求你必须处理线程安全。更改此内容非常尴尬,您必须编写自己的注册过程并使用[ComRegisterFunction]属性对其进行注释。

简单的方法是将键设置为“Both”并检查类构造函数中的单元状态。使用Thread.GetCurrentThread()。GetApartmentState()。如果您获得MTA,则抛出异常以告知客户端您不支持多线程。很多.NET类都可以做到这一点。

答案 1 :(得分:2)

有关执行必要注册表巫毒的ComRegisterFunction的示例,请参阅this answer。在某些情况下,您可能会想要这样 - 例如当你想确保你的线程是STA时,你可以与只需要STA线程使用的其他COM对象进行交互。