Gan*_*ant 7 c# com multithreading interop marshalling
我是COM的新手,试图理解STA和MTA之间的区别.我试图创建一个示例,该示例将显示COM可以管理在STA中创建的对象的调用,该对象不是线程安全的.
MyCalcServer这里的类是使用ATL Simple Object创建的.使用的设置与本文中的相同:
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();
}
}
Run Code Online (Sandbox Code Playgroud)
但是,这总是导致在InvalidCastExceptiont1的代码中引发(E_NOINTERFACE).我也尝试将ApartmentState更改为MTA但没有成功.
无法将"MyCOMLib.MyCalcServerClass"类型的COM对象强制转换为接口类型"MyCOMLib.IMyCalcServer".此操作失败,因为由于以下错误,对IID为"{B005DB8C-7B21-4898-9DEC-CBEBE175BB21}"的接口的COM组件的QueryInterface调用失败:不支持此类接口(HRESULT异常:0x80004002(E_NOINTERFACE)) .
有人可以解释我在这里做错了吗?
您明确要求 COM 为主线程创建实例,然后将其传递给另一个线程。当然在某些情况下是允许的(例如将 MyCalcServer 声明为多线程)。
但就您而言,您似乎需要为另一个线程创建代理。在常规 COM 客户端中,它是由 CoMarshalInterThreadInterfaceInStream 完成的。有一篇大文章来澄清它http://www.codeproject.com/KB/COM/cominterop.aspx