无法从STA线程调用从STAThread创建的COM对象 [英] Cannot call COM object created from STAThread from oher STA threads

查看:197
本文介绍了无法从STA线程调用从STAThread创建的COM对象的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I am new to COM and trying to understand the difference between STA and MTA. I tried to create an example that would show that COM can manage calls to object created in STA that is not thread-safe.

MyCalcServer 这里的类是使用ATL Simple Object创建的。使用的设置与本文中的设置相同:

MyCalcServer class here is created using ATL Simple Object. The settings used are the same as in this article:


  • 线程模型:公寓

  • 聚合: / li>
  • 介面
  • Threading Model: Apartment
  • Aggregation: No
  • Interface: Custom

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

MyCalcServer COM object is used in another C# project which is:

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();

    }
}

code> InvalidCastException (E_NOINTERFACE)在t1的代码内引发。我也试过将ApartmentState更改为MTA,但没有成功。

However, this always results in InvalidCastException (E_NOINTERFACE) raised inside t1's code. I have also tried changing ApartmentState to MTA with no success.


无法投射类型为
的COM对象'MyCOMLib.MyCalcServerClass'到
接口类型
' MyCOMLib.IMyCalcServer'。此
操作失败,因为$ II
接口的COM
组件上的
QueryInterface调用与IID
'{B005DB8C-7B21-4898-9DEC-CBEBE175BB21}'
失败由于以下错误:没有
这种接口支持(异常
从HRESULT:0x80004002
(E_NOINTERFACE))。

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声明为多线程)。

You explicitly ask COM to create instance for main thread, then you pass this to another thread. Of course in some circumstance it is allowed (for example declare MyCalcServer as multithread).

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

But in your case it looks you need create proxy for another thread. In regular COM clients it is done by CoMarshalInterThreadInterfaceInStream. There is large article to clarify it http://www.codeproject.com/KB/COM/cominterop.aspx

这篇关于无法从STA线程调用从STAThread创建的COM对象的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆