控制.NET进程外服务器服务的COM对象的线程模型

控制.NET进程外服务器服务的COM对象的线程模型,.net,com,localserver,.net,Com,Localserver,在用C#创建进程外COM服务器时,如Microsoft的All-in-One代码示例所述:,似乎很难控制(由客户端)在服务器中创建的对象的线程模型 正在创建的对象需要在STA中,因为它使用WPF对象,并且它的工厂正在注册,如的第95行所示,并粘贴在下面 private void PreMessageLoop() { // // Register the COM class factories. // Guid clsidSimpleObj = new Guid

在用C#创建进程外COM服务器时,如Microsoft的All-in-One代码示例所述:,似乎很难控制(由客户端)在服务器中创建的对象的线程模型

正在创建的对象需要在STA中,因为它使用WPF对象,并且它的工厂正在注册,如的第95行所示,并粘贴在下面

private void PreMessageLoop()
{
    //
    // Register the COM class factories.
    // 

    Guid clsidSimpleObj = new Guid(SimpleObject.ClassId);

    // Register the SimpleObject class object
    int hResult = COMNative.CoRegisterClassObject(
        ref clsidSimpleObj,                 // CLSID to be registered
        new SimpleObjectClassFactory(),     // Class factory
        CLSCTX.LOCAL_SERVER,                // Context to run
        REGCLS.MULTIPLEUSE | REGCLS.SUSPENDED,
        out _cookieSimpleObj);
    if (hResult != 0)
    {
        throw new ApplicationException(
        "CoRegisterClassObject failed w/err 0x" + hResult.ToString("X"));
    }
但是,CreateInstance函数总是在MTA中的新线程中调用。本地服务器的主线程标记(并验证)为STA线程似乎并不重要

已发现的所有关于该事项的材料都暗示,所创建对象的单元应与工厂注册所在线程的单元相匹配。事实上,这似乎是在使用ATL COM服务器(与托管C++混合创建对象)时,但这种方法似乎是向工作流程注入新线程,而初始化参数,特别是COM线程模型,似乎不可更改。
是否有人在不使用主要用非托管代码编写的COM服务器的情况下解决了此问题。

最近,我们在设置WinForm应用程序以承载64位互操作的某些对象时遇到了非常类似的情况。UI线程在启动时进入STA(带有STAThread属性)。不久,我们发现所有构造函数都在UI线程(STA)中运行,但所有其他方法都在.Net创建的工作线程(MTA)中运行

问题并不在于MTA,但我们确实有访问UI的方法,而且它们总是在一个工作线程中运行,这让我们感到困扰。虽然我们不知道如何强制.Net封送对UI线程(STA)的调用,但我们确实想出了一些非常肮脏的技巧,包括ContextBoundObject和方法拦截。我不会详细介绍,但您可以查看System.Runtime.Remoting.Messaging和System.Runtime.Remoting.Contexts命名空间。其思想是欺骗CCW将透明代理视为互操作对象,我们拦截对代理的每次调用,将消息传递给UI线程,然后将消息反向转换为方法调用。肮脏?对演出非常糟糕。但它是有效的


如果你想查看方法拦截代码,你可以给我发封电子邮件。

啊,我讨厌他们说的废话。当MSDN论坛在中国被聘用时,我与他们有着密切的联系。那时我是一名社区mod。图书馆根本不是同行评审的,它跨越了“55%准确率”的角度。尤其是那个叫“葛”的家伙,因为他的无知而非常危险。服务器的线程模型受服务器初始化COM的方式的影响。不是客户。谢谢你的洞察力。。。但是这个例子对于它所做的工作来说似乎已经足够好了。让MTA初始化我们的对象在技术上并不是不正确的。令人困惑的是,服务器的主线程属于STA,而框架(COM、OLE等)在服务器的MTA中创建了一个新线程来调用我们工厂的CreateInstance。