gpt4 book ai didi

c# - 无法从其他 STA 线程调用从 STAThread 创建的 COM 对象

转载 作者:太空狗 更新时间:2023-10-29 20:32:27 24 4
gpt4 key购买 nike

我是 COM 的新手,正在尝试了解 STA 和 MTA 之间的区别。我试图创建一个示例来说明 COM 可以管理对在 STA 中创建的非线程安全对象的调用。

MyCalcServer 类是使用 ATL 简单对象创建的。使用的设置与 this article 中的设置相同:

  • 线程模型:单元
  • 聚合:
  • 接口(interface):自定义

MyCalcServer COM 对象用于另一个 C# 项目:

class Program
{
[STAThread]
static void Main(string[] args)
{
MyCOMLib.MyCalcServer instance = new MyCOMLib.MyCalcServer();
string output1;
instance.ChangeValue("Gant", out output1);
Console.WriteLine(output1);


Thread t1 = new Thread(() =>
{
while (true)
{
string output;
instance.ChangeValue("Gant", out output);
Console.WriteLine(output);
}
});
t1.SetApartmentState(ApartmentState.STA);
t1.Start();

// :
// also has t2 and t3 here with similar code
// :

t1.Join(); t2.Join(); t3.Join();

}
}

但是,这总是会导致在 t1 的代码中引发 InvalidCastException (E_NOINTERFACE)。我也曾尝试将 ApartmentState 更改为 MTA,但没有成功。

Unable to cast COM object of type 'MyCOMLib.MyCalcServerClass' to interface type 'MyCOMLib.IMyCalcServer'. This operation failed because the QueryInterface call on the COM component for the interface with IID '{B005DB8C-7B21-4898-9DEC-CBEBE175BB21}' failed due to the following error: No such interface supported (Exception from HRESULT: 0x80004002 (E_NOINTERFACE)).

谁能解释一下我在这里做错了什么?

最佳答案

您明确要求 COM 为主线程创建实例,然后将其传递给另一个线程。当然在某些情况下是允许的(例如将 MyCalcServer 声明为多线程)。

但在您的情况下,您似乎需要为另一个线程创建代理。在常规 COM 客户端中,它由 CoMarshalInterThreadInterfaceInStream 完成。有大篇文章澄清一下http://www.codeproject.com/KB/COM/cominterop.aspx

关于c# - 无法从其他 STA 线程调用从 STAThread 创建的 COM 对象,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2175419/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com