【发布时间】:2010-10-11 19:42:12
【问题描述】:
在使用 C# 创建进程外 COM 服务器时,如 Microsoft 的 All-In-One 代码示例中所述:CSExeCOMServer,似乎很难控制在服务器中创建的对象的线程模型(由客户)。
正在创建的对象需要在 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 服务器(与托管 C++ 混合创建对象)时的情况,但这种方法似乎是将一个新线程注入到初始化参数的工作流中,特别是 COM 线程模型, 似乎不可更改。
有没有人在不求助于主要用非托管代码编写的 COM 服务器的情况下解决了这个问题。
【问题讨论】:
-
呃,我讨厌他们想出的废话。当他们在中国被录用时,我与 MSDN 论坛密切相关。那时我是一个社区模组。该库根本没有经过同行评审,它跨越了“55% 准确”的角度。尤其是那个叫“哥”的家伙,对于他的无知,是非常危险的。服务器的线程模型受服务器如何初始化 COM 的影响。不是客户。
-
感谢您的洞察力...但是该示例似乎可以很好地完成它的工作。让 MTA 初始化我们的对象在技术上并不是不正确的。令人困惑的部分是 SERVER 的主线程属于一个 STA,但框架(COM、OLE 等)在服务器中创建了一个新线程,该线程位于服务器的 MTA 中,以调用我们工厂的 CreateInstance。
标签: .net com localserver