2010-10-11 99 views
2

在Microsoft的All-In-One代碼示例CSExeCOMServer中記錄的C#中創建進程外COM服務器時,似乎很難控制線程模型的服務器中創建的對象(由客戶端)。控制.NET進程服務器提供的COM對象的線程模型

對象被創建需要在一個STA由於它使用WPF對象,並且表現出對線的ExeCOMServer.cs 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服務器(與Managed C++混合創建對象)時,似乎就是這種情況,但是此方法似乎將一個新線程注入了初始化參數的工作流,特別是COM線程模型,似乎不可更改。

有沒有人解決這個問題,而不訴諸於主要寫在非託管代碼中的COM服務器。

+1

呃,我*討厭他們提出的廢話。當他們在中國受僱時,我與MSDN論壇密切相關。當時我是一個社區mod。圖書館根本沒有同行評議,它跨越了「55%準確」的角度。尤其是那個叫「葛」的人,對他的無知是非常危險的。服務器的線程模型受服務器初始化COM的方式影響。不是客戶。 – 2010-10-11 22:34:42

+0

感謝您的洞察力......但這個例子似乎對它的功能足夠好。讓MTA初始化我們的對象在技術上並不正確。令人困惑的部分是_SERVER_的主線程屬於STA,但框架(COM,OLE,無論)在服務器的MTA中的服務器中創建一個新線程,以調用Factory的CreateInstance。 – Steven 2010-10-12 00:36:50

回答

2

最近,在設置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線程,然後將消息反向轉換爲方法調用。髒?是。性能?很壞。但它很有效。

如果您想查看方法攔截代碼,可以給我發一封電子郵件。