我是COM新手,试图理解STA和MTA之间的区别。我试图创建一个示例,它将显示COM可以管理对STA中创建的非线程安全对象的调用。无法从其他STA线程调用STAThread创建的COM对象
MyCalcServer
这里的类是使用ATL Simple Object创建的。使用的设置是一样this article:
- 线程模型:公寓
- 聚合:没有
- 接口:定制
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)).
有没有人请解释我在做什么错在这里?
也许JIT认为你没有使用“实例”并尽早发布它。 尝试在连接后放置Marshal.ReleaseComObject(实例)。 – adrianm 2010-02-01 08:50:19
@adrianm仍然无法正常工作,但是这要感谢 – Gant 2010-02-01 08:57:32
尝试将第一行更改为MyCOMLib.IMyCalcServer instance = new MyCOMLib.MyCalcServer(); 我认为只有接口(不是类)可以在线程之间编组。 – adrianm 2010-02-01 23:00:01